Merge topic 'CheckCXXSymbolExists-c++-syntax'

72fcadb007 CheckCXXSymbolExists: Make C++-syntax symbols work on more compilers

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !3545
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index 8712fb9..5de117b 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -288,6 +288,7 @@
             \ SKIP_AUTORCC
             \ SKIP_AUTOUIC
             \ SKIP_BUILD_RPATH
+            \ SKIP_REGULAR_EXPRESSION
             \ SKIP_RETURN_CODE
             \ SOURCES
             \ SOURCE_DIR
@@ -1772,6 +1773,7 @@
             \ NAME
             \ OFF
             \ PASS_REGULAR_EXPRESSION
+            \ SKIP_REGULAR_EXPRESSION
             \ TARGET_FILE
             \ WILL_FAIL
             \ WORKING_DIRECTORY
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 399e79c..5efa077 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -429,10 +429,7 @@
     set(_CMAKE_USE_OPENSSL_DEFAULT OFF)
     if(NOT DEFINED CMAKE_USE_OPENSSL AND NOT WIN32 AND NOT APPLE
         AND CMAKE_SYSTEM_NAME MATCHES "(Linux|FreeBSD)")
-      find_package(OpenSSL QUIET)
-      if(OPENSSL_FOUND)
-        set(_CMAKE_USE_OPENSSL_DEFAULT ON)
-      endif()
+      set(_CMAKE_USE_OPENSSL_DEFAULT ON)
     endif()
     option(CMAKE_USE_OPENSSL "Use OpenSSL." ${_CMAKE_USE_OPENSSL_DEFAULT})
     mark_as_advanced(CMAKE_USE_OPENSSL)
diff --git a/Help/command/add_test.rst b/Help/command/add_test.rst
index 884b2ee..a77ba37 100644
--- a/Help/command/add_test.rst
+++ b/Help/command/add_test.rst
@@ -38,8 +38,9 @@
 non-zero to fail, or vice-versa if the :prop_test:`WILL_FAIL` test
 property is set.  Any output written to stdout or stderr will be
 captured by :manual:`ctest(1)` but does not affect the pass/fail status
-unless the :prop_test:`PASS_REGULAR_EXPRESSION` or
-:prop_test:`FAIL_REGULAR_EXPRESSION` test property is used.
+unless the :prop_test:`PASS_REGULAR_EXPRESSION`,
+:prop_test:`FAIL_REGULAR_EXPRESSION` or
+:prop_test:`SKIP_REGULAR_EXPRESSION` test property is used.
 
 The ``COMMAND`` and ``WORKING_DIRECTORY`` options may use "generator
 expressions" with the syntax ``$<...>``.  See the
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index 6e1d232..2186bd8 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -293,13 +293,15 @@
    The package root variables are maintained as a stack so if
    called from within a find module, root paths from the parent's find
    module will also be searched after paths for the current package.
-   This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed.
+   This can be skipped if ``NO_PACKAGE_ROOT_PATH`` is passed or by setting
+   the :variable:`CMAKE_FIND_USE_PACKAGE_ROOT_PATH` to ``FALSE``.
    See policy :policy:`CMP0074`.
 
 2. Search paths specified in cmake-specific cache variables.  These
    are intended to be used on the command line with a ``-DVAR=value``.
    The values are interpreted as :ref:`semicolon-separated lists <CMake Language Lists>`.
-   This can be skipped if ``NO_CMAKE_PATH`` is passed::
+   This can be skipped if ``NO_CMAKE_PATH`` is passed or by setting the
+   :variable:`CMAKE_FIND_USE_CMAKE_PATH` to ``FALSE``::
 
      CMAKE_PREFIX_PATH
      CMAKE_FRAMEWORK_PATH
@@ -309,7 +311,8 @@
    These are intended to be set in the user's shell configuration,
    and therefore use the host's native path separator
    (``;`` on Windows and ``:`` on UNIX).
-   This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed::
+   This can be skipped if ``NO_CMAKE_ENVIRONMENT_PATH`` is passed or by setting
+   the :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH` to ``FALSE``::
 
      <PackageName>_DIR
      CMAKE_PREFIX_PATH
@@ -322,7 +325,8 @@
    be specified with the ``PATHS`` option.
 
 5. Search the standard system environment variables.  This can be
-   skipped if ``NO_SYSTEM_ENVIRONMENT_PATH`` is passed.  Path entries
+   skipped if ``NO_SYSTEM_ENVIRONMENT_PATH`` is passed  or by setting the
+   :variable:`CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH` to ``FALSE``. Path entries
    ending in ``/bin`` or ``/sbin`` are automatically converted to their
    parent directories::
 
@@ -339,7 +343,8 @@
 
 7. Search cmake variables defined in the Platform files for the
    current system.  This can be skipped if ``NO_CMAKE_SYSTEM_PATH`` is
-   passed::
+   passed or by setting the :variable:`CMAKE_FIND_USE_CMAKE_SYSTEM_PATH`
+   to ``FALSE``::
 
      CMAKE_SYSTEM_PREFIX_PATH
      CMAKE_SYSTEM_FRAMEWORK_PATH
diff --git a/Help/command/install.rst b/Help/command/install.rst
index ab6fef6..5affc5b 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -126,6 +126,8 @@
   marked with the ``FRAMEWORK`` property on macOS (see ``FRAMEWORK``
   below.) For DLL platforms (all Windows-based systems including
   Cygwin), the DLL import library is treated as an ``ARCHIVE`` target.
+  On AIX, the linker import file created for executables with
+  :prop_tgt:`ENABLE_EXPORTS` is treated as an ``ARCHIVE`` target.
 
 ``LIBRARY``
   Module libraries are always treated as ``LIBRARY`` targets. For non-
diff --git a/Help/command/message.rst b/Help/command/message.rst
index 5dca6b4..3002842 100644
--- a/Help/command/message.rst
+++ b/Help/command/message.rst
@@ -60,6 +60,11 @@
 interactive pop-up box.  The ``--loglevel`` command-line option to each of
 these tools can be used to control which messages will be shown.
 
+Messages of log levels ``NOTICE`` and below will also have each line preceded
+by the content of the :variable:`CMAKE_MESSAGE_INDENT` variable (converted to
+a single string by concatenating its list items).  For ``STATUS`` to ``TRACE``
+messages, this indenting content will be inserted after the hyphens.
+
 CMake Warning and Error message text displays using a simple markup
 language.  Non-indented text is formatted in line-wrapped paragraphs
 delimited by newlines.  Indented text is considered pre-formatted.
diff --git a/Help/command/string.rst b/Help/command/string.rst
index 2e89d7b..81a2061 100644
--- a/Help/command/string.rst
+++ b/Help/command/string.rst
@@ -22,8 +22,8 @@
     string(`PREPEND`_ <string-var> [<input>...])
     string(`CONCAT`_ <out-var> [<input>...])
     string(`JOIN`_ <glue> <out-var> [<input>...])
-    string(`TOLOWER`_ <string1> <out-var>)
-    string(`TOUPPER`_ <string1> <out-var>)
+    string(`TOLOWER`_ <string> <out-var>)
+    string(`TOUPPER`_ <string> <out-var>)
     string(`LENGTH`_ <string> <out-var>)
     string(`SUBSTRING`_ <string> <begin> <length> <out-var>)
     string(`STRIP`_ <string> <out-var>)
@@ -38,7 +38,7 @@
 
   `Generation`_
     string(`ASCII`_ <number>... <out-var>)
-    string(`CONFIGURE`_ <string1> <out-var> [...])
+    string(`CONFIGURE`_ <string> <out-var> [...])
     string(`MAKE_C_IDENTIFIER`_ <string> <out-var>)
     string(`RANDOM`_ [<option>...] <out-var>)
     string(`TIMESTAMP`_ <out-var> [<format string>] [UTC])
@@ -51,23 +51,28 @@
 
 .. code-block:: cmake
 
-  string(FIND <string> <substring> <output variable> [REVERSE])
+  string(FIND <string> <substring> <output_variable> [REVERSE])
 
-Return the position where the given substring was found in
-the supplied string.  If the ``REVERSE`` flag was used, the command will
+Return the position where the given ``<substring>`` was found in
+the supplied ``<string>``.  If the ``REVERSE`` flag was used, the command will
 search for the position of the last occurrence of the specified
-substring.  If the substring is not found, a position of -1 is returned.
+``<substring>``.  If the ``<substring>`` is not found, a position of -1 is
+returned.
+
+The ``string(FIND)`` subcommand treats all strings as ASCII-only characters.
+The index stored in ``<output_variable>`` will also be counted in bytes,
+so strings containing multi-byte characters may lead to unexpected results.
 
 .. _REPLACE:
 
 .. code-block:: cmake
 
   string(REPLACE <match_string>
-         <replace_string> <output variable>
+         <replace_string> <output_variable>
          <input> [<input>...])
 
-Replace all occurrences of ``match_string`` in the input
-with ``replace_string`` and store the result in the output.
+Replace all occurrences of ``<match_string>`` in the ``<input>``
+with ``<replace_string>`` and store the result in the ``<output_variable>``.
 
 Regular Expressions
 ^^^^^^^^^^^^^^^^^^^
@@ -77,9 +82,10 @@
 .. code-block:: cmake
 
   string(REGEX MATCH <regular_expression>
-         <output variable> <input> [<input>...])
+         <output_variable> <input> [<input>...])
 
-Match the regular expression once and store the match in the output variable.
+Match the ``<regular_expression>`` once and store the match in the
+``<output_variable>``.
 All ``<input>`` arguments are concatenated before matching.
 
 .. _`REGEX MATCHALL`:
@@ -87,10 +93,10 @@
 .. code-block:: cmake
 
   string(REGEX MATCHALL <regular_expression>
-         <output variable> <input> [<input>...])
+         <output_variable> <input> [<input>...])
 
-Match the regular expression as many times as possible and store the matches
-in the output variable as a list.
+Match the ``<regular_expression>`` as many times as possible and store the
+matches in the ``<output_variable>`` as a list.
 All ``<input>`` arguments are concatenated before matching.
 
 .. _`REGEX REPLACE`:
@@ -98,16 +104,17 @@
 .. code-block:: cmake
 
   string(REGEX REPLACE <regular_expression>
-         <replace_expression> <output variable>
+         <replacement_expression> <output_variable>
          <input> [<input>...])
 
-Match the regular expression as many times as possible and substitute the
-replacement expression for the match in the output.
+Match the ``<regular_expression>`` as many times as possible and substitute
+the ``<replacement_expression>`` for the match in the output.
 All ``<input>`` arguments are concatenated before matching.
 
-The replace expression may refer to paren-delimited subexpressions of the
-match using ``\1``, ``\2``, ..., ``\9``.  Note that two backslashes (``\\1``)
-are required in CMake code to get a backslash through argument parsing.
+The ``<replacement_expression>`` may refer to parenthesis-delimited
+subexpressions of the match using ``\1``, ``\2``, ..., ``\9``.  Note that
+two backslashes (``\\1``) are required in CMake code to get a backslash
+through argument parsing.
 
 .. _`Regex Specification`:
 
@@ -180,103 +187,109 @@
 
 .. code-block:: cmake
 
-  string(APPEND <string variable> [<input>...])
+  string(APPEND <string_variable> [<input>...])
 
-Append all the input arguments to the string.
+Append all the ``<input>`` arguments to the string.
 
 .. _PREPEND:
 
 .. code-block:: cmake
 
-  string(PREPEND <string variable> [<input>...])
+  string(PREPEND <string_variable> [<input>...])
 
-Prepend all the input arguments to the string.
+Prepend all the ``<input>`` arguments to the string.
 
 .. _CONCAT:
 
 .. code-block:: cmake
 
-  string(CONCAT <output variable> [<input>...])
+  string(CONCAT <output_variable> [<input>...])
 
-Concatenate all the input arguments together and store
-the result in the named output variable.
+Concatenate all the ``<input>`` arguments together and store
+the result in the named ``<output_variable>``.
 
 .. _JOIN:
 
 .. code-block:: cmake
 
-  string(JOIN <glue> <output variable> [<input>...])
+  string(JOIN <glue> <output_variable> [<input>...])
 
-Join all the input arguments together using the glue
-string and store the result in the named output variable.
+Join all the ``<input>`` arguments together using the ``<glue>``
+string and store the result in the named ``<output_variable>``.
 
-To join list's elements, use preferably the ``JOIN`` operator
-from :command:`list` command. This allows for the elements to have
+To join a list's elements, prefer to use the ``JOIN`` operator
+from the :command:`list` command.  This allows for the elements to have
 special characters like ``;`` in them.
 
 .. _TOLOWER:
 
 .. code-block:: cmake
 
-  string(TOLOWER <string1> <output variable>)
+  string(TOLOWER <string> <output_variable>)
 
-Convert string to lower characters.
+Convert ``<string>`` to lower characters.
 
 .. _TOUPPER:
 
 .. code-block:: cmake
 
-  string(TOUPPER <string1> <output variable>)
+  string(TOUPPER <string> <output_variable>)
 
-Convert string to upper characters.
+Convert ``<string>`` to upper characters.
 
 .. _LENGTH:
 
 .. code-block:: cmake
 
-  string(LENGTH <string> <output variable>)
+  string(LENGTH <string> <output_variable>)
 
-Store in an output variable a given string's length.
+Store in an ``<output_variable>`` a given string's length in bytes.
+Note that this means if ``<string>`` contains multi-byte characters, the
+result stored in ``<output_variable>`` will *not* be the number of characters.
 
 .. _SUBSTRING:
 
 .. code-block:: cmake
 
-  string(SUBSTRING <string> <begin> <length> <output variable>)
+  string(SUBSTRING <string> <begin> <length> <output_variable>)
 
-Store in an output variable a substring of a given string.  If length is
-``-1`` the remainder of the string starting at begin will be returned.
-If string is shorter than length then end of string is used instead.
+Store in an ``<output_variable>`` a substring of a given ``<string>``.  If
+``<length>`` is ``-1`` the remainder of the string starting at ``<begin>``
+will be returned.  If ``<string>`` is shorter than ``<length>`` then the
+end of the string is used instead.
+
+Both ``<begin>`` and ``<length>`` are counted in bytes, so care must
+be exercised if ``<string>`` could contain multi-byte characters.
 
 .. note::
-  CMake 3.1 and below reported an error if length pointed past
-  the end of string.
+  CMake 3.1 and below reported an error if ``<length>`` pointed past
+  the end of ``<string>``.
 
 .. _STRIP:
 
 .. code-block:: cmake
 
-  string(STRIP <string> <output variable>)
+  string(STRIP <string> <output_variable>)
 
-Store in an output variable a substring of a given string with leading and
-trailing spaces removed.
+Store in an ``<output_variable>`` a substring of a given ``<string>`` with
+leading and trailing spaces removed.
 
 .. _GENEX_STRIP:
 
 .. code-block:: cmake
 
-  string(GENEX_STRIP <input string> <output variable>)
+  string(GENEX_STRIP <string> <output_variable>)
 
 Strip any :manual:`generator expressions <cmake-generator-expressions(7)>`
-from the ``input string`` and store the result in the ``output variable``.
+from the input ``<string>`` and store the result in the ``<output_variable>``.
 
 .. _REPEAT:
 
 .. code-block:: cmake
 
-  string(REPEAT <input string> <count> <output variable>)
+  string(REPEAT <string> <count> <output_variable>)
 
-Produce the output string as repetion of ``input string`` ``count`` times.
+Produce the output string as the input ``<string>`` repeated ``<count>`` times.
 
 Comparison
 ^^^^^^^^^^
@@ -285,14 +298,14 @@
 
 .. code-block:: cmake
 
-  string(COMPARE LESS <string1> <string2> <output variable>)
-  string(COMPARE GREATER <string1> <string2> <output variable>)
-  string(COMPARE EQUAL <string1> <string2> <output variable>)
-  string(COMPARE NOTEQUAL <string1> <string2> <output variable>)
-  string(COMPARE LESS_EQUAL <string1> <string2> <output variable>)
-  string(COMPARE GREATER_EQUAL <string1> <string2> <output variable>)
+  string(COMPARE LESS <string1> <string2> <output_variable>)
+  string(COMPARE GREATER <string1> <string2> <output_variable>)
+  string(COMPARE EQUAL <string1> <string2> <output_variable>)
+  string(COMPARE NOTEQUAL <string1> <string2> <output_variable>)
+  string(COMPARE LESS_EQUAL <string1> <string2> <output_variable>)
+  string(COMPARE GREATER_EQUAL <string1> <string2> <output_variable>)
 
-Compare the strings and store true or false in the output variable.
+Compare the strings and store true or false in the ``<output_variable>``.
 
 .. _`Supported Hash Algorithms`:
 
@@ -303,9 +316,9 @@
 
 .. code-block:: cmake
 
-  string(<HASH> <output variable> <input>)
+  string(<HASH> <output_variable> <input>)
 
-Compute a cryptographic hash of the input string.
+Compute a cryptographic hash of the ``<input>`` string.
 The supported ``<HASH>`` algorithm names are:
 
 ``MD5``
@@ -336,7 +349,7 @@
 
 .. code-block:: cmake
 
-  string(ASCII <number> [<number> ...] <output variable>)
+  string(ASCII <number> [<number> ...] <output_variable>)
 
 Convert all numbers into corresponding ASCII characters.
 
@@ -344,31 +357,31 @@
 
 .. code-block:: cmake
 
-  string(CONFIGURE <string1> <output variable>
+  string(CONFIGURE <string> <output_variable>
          [@ONLY] [ESCAPE_QUOTES])
 
-Transform a string like :command:`configure_file` transforms a file.
+Transform a ``<string>`` like :command:`configure_file` transforms a file.
 
 .. _MAKE_C_IDENTIFIER:
 
 .. code-block:: cmake
 
-  string(MAKE_C_IDENTIFIER <input string> <output variable>)
+  string(MAKE_C_IDENTIFIER <string> <output_variable>)
 
-Convert each non-alphanumeric character in the ``<input string>`` to an
-underscore and store the result in the ``<output variable>``.  If the first
-character of the string is a digit, an underscore will also be prepended to
-the result.
+Convert each non-alphanumeric character in the input ``<string>`` to an
+underscore and store the result in the ``<output_variable>``.  If the first
+character of the ``<string>`` is a digit, an underscore will also be prepended
+to the result.
 
 .. _RANDOM:
 
 .. code-block:: cmake
 
   string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]
-         [RANDOM_SEED <seed>] <output variable>)
+         [RANDOM_SEED <seed>] <output_variable>)
 
-Return a random string of given length consisting of
-characters from the given alphabet.  Default length is 5 characters
+Return a random string of given ``<length>`` consisting of
+characters from the given ``<alphabet>``.  Default length is 5 characters
 and default alphabet is all numbers and upper and lower case letters.
 If an integer ``RANDOM_SEED`` is given, its value will be used to seed the
 random number generator.
@@ -377,18 +390,18 @@
 
 .. code-block:: cmake
 
-  string(TIMESTAMP <output variable> [<format string>] [UTC])
+  string(TIMESTAMP <output_variable> [<format_string>] [UTC])
 
 Write a string representation of the current date
-and/or time to the output variable.
+and/or time to the ``<output_variable>``.
 
-Should the command be unable to obtain a timestamp the output variable
-will be set to the empty string "".
+If the command is unable to obtain a timestamp, the ``<output_variable>``
+will be set to the empty string ``""``.
 
 The optional ``UTC`` flag requests the current date/time representation to
 be in Coordinated Universal Time (UTC) rather than local time.
 
-The optional ``<format string>`` may contain the following format
+The optional ``<format_string>`` may contain the following format
 specifiers:
 
 ::
@@ -415,7 +428,7 @@
 Unknown format specifiers will be ignored and copied to the output
 as-is.
 
-If no explicit ``<format string>`` is given it will default to:
+If no explicit ``<format_string>`` is given, it will default to:
 
 ::
 
@@ -432,7 +445,7 @@
 
 .. code-block:: cmake
 
-  string(UUID <output variable> NAMESPACE <namespace> NAME <name>
+  string(UUID <output_variable> NAMESPACE <namespace> NAME <name>
          TYPE <MD5|SHA1> [UPPER])
 
 Create a universally unique identifier (aka GUID) as per RFC4122
@@ -441,6 +454,6 @@
 The hash algorithm can be either ``MD5`` (Version 3 UUID) or
 ``SHA1`` (Version 5 UUID).
 A UUID has the format ``xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx``
-where each `x` represents a lower case hexadecimal character.
-Where required an uppercase representation can be requested
+where each ``x`` represents a lower case hexadecimal character.
+Where required, an uppercase representation can be requested
 with the optional ``UPPER`` flag.
diff --git a/Help/dev/maint.rst b/Help/dev/maint.rst
index 1153a09..37a1d3a 100644
--- a/Help/dev/maint.rst
+++ b/Help/dev/maint.rst
@@ -92,6 +92,45 @@
 .. _`CMake Review Process`: review.rst
 .. _`CMake CDash Page`: https://open.cdash.org/index.php?project=CMake
 
+Create Release Version
+======================
+
+When the ``release`` branch is ready to create a new release, follow the
+steps in the above `Maintain Current Release`_ section to checkout a local
+``release-$ver`` branch, where ``$ver`` is the version number of the
+current release in the form ``$major.$minor``.
+
+Edit ``Source/CMakeVersion.cmake`` to set the full version:
+
+.. code-block:: cmake
+
+  # CMake version number components.
+  set(CMake_VERSION_MAJOR $major)
+  set(CMake_VERSION_MINOR $minor)
+  set(CMake_VERSION_PATCH $patch)
+  #set(CMake_VERSION_RC $rc) # uncomment for release candidates
+
+In the following we use the placeholder ``$fullver`` for the full version
+number of the new release with the form ``$major.$minor.$patch[-rc$rc]``.
+If the version is not a release candidate, comment out the RC version
+component above and leave off the ``-rc$rc`` suffix from ``$fullver``.
+
+Commit the release version with the **exact** message ``CMake $fullver``:
+
+.. code-block:: shell
+
+  git commit -m "CMake $fullver"
+
+Tag the release using an annotated tag with the same message as the
+commit and named with the **exact** form ``v$fullver``:
+
+.. code-block:: shell
+
+  git tag -s -m "CMake $fullver" "v$fullver"
+
+Follow the steps in the above `Maintain Current Release`_ section to
+merge the ``release-$ver`` branch into ``master`` and publish both.
+
 Branch a New Release
 ====================
 
@@ -178,7 +217,7 @@
   the CMake Release Notes index page.
 
 Update ``Source/CMakeVersion.cmake`` to set the version to
-``$major.$minor.0-rc1``:
+``$major.$minor.0-rc0``:
 
 .. code-block:: cmake
 
@@ -186,7 +225,7 @@
   set(CMake_VERSION_MAJOR $major)
   set(CMake_VERSION_MINOR $minor)
   set(CMake_VERSION_PATCH 0)
-  set(CMake_VERSION_RC 1)
+  set(CMake_VERSION_RC 0)
 
 Update uses of ``DEVEL_CMAKE_VERSION`` in the source tree to mention the
 actual version number:
@@ -197,7 +236,7 @@
 
 Commit with a message such as::
 
-  CMake $major.$minor.0-rc1 version update
+  Begin $ver release versioning
 
 Merge the ``release-$ver`` branch to ``master``:
 
@@ -225,7 +264,7 @@
   set(CMake_VERSION_MAJOR $major)
   set(CMake_VERSION_MINOR $minor)
   set(CMake_VERSION_PATCH $date)
-  #set(CMake_VERSION_RC 1)
+  #set(CMake_VERSION_RC 0)
 
 Commit with a message such as::
 
diff --git a/Help/guide/tutorial/Complete/CMakeLists.txt b/Help/guide/tutorial/Complete/CMakeLists.txt
index e84f932..4541392 100644
--- a/Help/guide/tutorial/Complete/CMakeLists.txt
+++ b/Help/guide/tutorial/Complete/CMakeLists.txt
@@ -1,7 +1,17 @@
-cmake_minimum_required(VERSION 3.3)
+cmake_minimum_required(VERSION 3.15)
 project(Tutorial)
 
-set(CMAKE_CXX_STANDARD 14)
+add_library(tutorial_compiler_flags INTERFACE)
+target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+
+# add compiler warning flags just when building this project via
+# the BUILD_INTERFACE genex
+set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU>")
+set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
+target_compile_options(tutorial_compiler_flags INTERFACE
+  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
+  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
+)
 
 # set the version number
 set(Tutorial_VERSION_MAJOR 1)
diff --git a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
index 63c0f5f..c12955d 100644
--- a/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Complete/MathFunctions/CMakeLists.txt
@@ -21,6 +21,7 @@
 
   # first we add the executable that generates the table
   add_executable(MakeTable MakeTable.cxx)
+  target_link_libraries(MakeTable tutorial_compiler_flags)
 
   # add the command to generate the source code
   add_custom_command(
@@ -44,14 +45,18 @@
                         POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
                         )
 
-  target_compile_definitions(SqrtLibrary PRIVATE
-                             "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>"
-                             "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>"
-                             )
+  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+
+
+  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+  if(HAVE_LOG AND HAVE_EXP)
+    target_compile_definitions(SqrtLibrary
+                               PRIVATE "HAVE_LOG" "HAVE_EXP")
+  endif()
   target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
 endif()
 
-target_compile_definitions(MathFunctions PRIVATE "$<$<BOOL:${USE_MYMATH}>:USE_MYMATH>")
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
 
 # define the symbol stating we are using the declspec(dllexport) when
 # building on windows
@@ -62,7 +67,7 @@
 set_property(TARGET MathFunctions PROPERTY SOVERSION "1")
 
 # install rules
-install(TARGETS MathFunctions
+install(TARGETS MathFunctions tutorial_compiler_flags
         DESTINATION lib
         EXPORT MathFunctionsTargets)
 install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Consumer/CMakeLists.txt b/Help/guide/tutorial/Consumer/CMakeLists.txt
index 5097917..4033b4d 100644
--- a/Help/guide/tutorial/Consumer/CMakeLists.txt
+++ b/Help/guide/tutorial/Consumer/CMakeLists.txt
@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 3.3)
 
 if(NOT DEFINED CMAKE_CXX_STANDARD)
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 11)
+  set(CMAKE_CXX_STANDARD_REQUIRED True)
 endif()
 
 
diff --git a/Help/guide/tutorial/Step10/CMakeLists.txt b/Help/guide/tutorial/Step10/CMakeLists.txt
index 5819272..25bc0c1 100644
--- a/Help/guide/tutorial/Step10/CMakeLists.txt
+++ b/Help/guide/tutorial/Step10/CMakeLists.txt
@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 3.3)
 project(Tutorial)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 # Set the version number
 set(Tutorial_VERSION_MAJOR 1)
diff --git a/Help/guide/tutorial/Step11/CMakeLists.txt b/Help/guide/tutorial/Step11/CMakeLists.txt
index 2e5cb15..e54bdde 100644
--- a/Help/guide/tutorial/Step11/CMakeLists.txt
+++ b/Help/guide/tutorial/Step11/CMakeLists.txt
@@ -1,7 +1,17 @@
-cmake_minimum_required(VERSION 3.3)
+cmake_minimum_required(VERSION 3.15)
 project(Tutorial)
 
-set(CMAKE_CXX_STANDARD 14)
+add_library(tutorial_compiler_flags INTERFACE)
+target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+
+# add compiler warning flags just when building this project via
+# the BUILD_INTERFACE genex
+set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU>")
+set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
+target_compile_options(tutorial_compiler_flags INTERFACE
+  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
+  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
+)
 
 # set the version number
 set(Tutorial_VERSION_MAJOR 1)
diff --git a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
index ea42770..daaaa55 100644
--- a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
@@ -19,6 +19,7 @@
 
   # first we add the executable that generates the table
   add_executable(MakeTable MakeTable.cxx)
+  target_link_libraries(MakeTable tutorial_compiler_flags)
 
   # add the command to generate the source code
   add_custom_command(
@@ -42,14 +43,17 @@
                         POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
                         )
 
-  target_compile_definitions(SqrtLibrary PRIVATE
-                             "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>"
-                             "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>"
-                             )
+  target_link_libraries(SqrtLibrary PUBLIC tutorial_compiler_flags)
+
+  target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
+  if(HAVE_LOG AND HAVE_EXP)
+    target_compile_definitions(SqrtLibrary
+                               PRIVATE "HAVE_LOG" "HAVE_EXP")
+  endif()
   target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
 endif()
 
-target_compile_definitions(MathFunctions PRIVATE "$<$<BOOL:${USE_MYMATH}>:USE_MYMATH>")
+target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
 
 # define the symbol stating we are using the declspec(dllexport) when
 #building on windows
diff --git a/Help/guide/tutorial/Step2/CMakeLists.txt b/Help/guide/tutorial/Step2/CMakeLists.txt
index 1f43b2b..059b89a 100644
--- a/Help/guide/tutorial/Step2/CMakeLists.txt
+++ b/Help/guide/tutorial/Step2/CMakeLists.txt
@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 3.3)
 project(Tutorial)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 # set the version number
 set(Tutorial_VERSION_MAJOR 1)
diff --git a/Help/guide/tutorial/Step3/CMakeLists.txt b/Help/guide/tutorial/Step3/CMakeLists.txt
index 966c38a..9804abf 100644
--- a/Help/guide/tutorial/Step3/CMakeLists.txt
+++ b/Help/guide/tutorial/Step3/CMakeLists.txt
@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 3.3)
 project(Tutorial)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 # should we use our own math functions
 option(USE_MYMATH "Use tutorial provided math implementation" ON)
diff --git a/Help/guide/tutorial/Step4/CMakeLists.txt b/Help/guide/tutorial/Step4/CMakeLists.txt
index a157bda..0ae2648 100644
--- a/Help/guide/tutorial/Step4/CMakeLists.txt
+++ b/Help/guide/tutorial/Step4/CMakeLists.txt
@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 3.3)
 project(Tutorial)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 # should we use our own math functions
 option(USE_MYMATH "Use tutorial provided math implementation" ON)
diff --git a/Help/guide/tutorial/Step5/CMakeLists.txt b/Help/guide/tutorial/Step5/CMakeLists.txt
index 76b9179..dac9b45 100644
--- a/Help/guide/tutorial/Step5/CMakeLists.txt
+++ b/Help/guide/tutorial/Step5/CMakeLists.txt
@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 3.3)
 project(Tutorial)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 # should we use our own math functions
 option(USE_MYMATH "Use tutorial provided math implementation" ON)
diff --git a/Help/guide/tutorial/Step6/CMakeLists.txt b/Help/guide/tutorial/Step6/CMakeLists.txt
index 5829891..1465e46 100644
--- a/Help/guide/tutorial/Step6/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/CMakeLists.txt
@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 3.3)
 project(Tutorial)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 # set the version number
 set(Tutorial_VERSION_MAJOR 1)
diff --git a/Help/guide/tutorial/Step7/CMakeLists.txt b/Help/guide/tutorial/Step7/CMakeLists.txt
index 17e6a60..a1efa77 100644
--- a/Help/guide/tutorial/Step7/CMakeLists.txt
+++ b/Help/guide/tutorial/Step7/CMakeLists.txt
@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 3.3)
 project(Tutorial)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 # set the version number
 set(Tutorial_VERSION_MAJOR 1)
diff --git a/Help/guide/tutorial/Step8/CMakeLists.txt b/Help/guide/tutorial/Step8/CMakeLists.txt
index 86725e8..a0316a0 100644
--- a/Help/guide/tutorial/Step8/CMakeLists.txt
+++ b/Help/guide/tutorial/Step8/CMakeLists.txt
@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 3.3)
 project(Tutorial)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 # set the version number
 set(Tutorial_VERSION_MAJOR 1)
diff --git a/Help/guide/tutorial/Step9/CMakeLists.txt b/Help/guide/tutorial/Step9/CMakeLists.txt
index 07ab90a..e610b99 100644
--- a/Help/guide/tutorial/Step9/CMakeLists.txt
+++ b/Help/guide/tutorial/Step9/CMakeLists.txt
@@ -1,7 +1,8 @@
 cmake_minimum_required(VERSION 3.3)
 project(Tutorial)
 
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED True)
 
 # set the version number
 set(Tutorial_VERSION_MAJOR 1)
diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst
index db8e7a0..068499e 100644
--- a/Help/guide/tutorial/index.rst
+++ b/Help/guide/tutorial/index.rst
@@ -228,7 +228,8 @@
 CMakeLists.
 
 Once this is done, run **cmake** or **cmake-gui** to configure the project
-and then build it with your chosen build tool.
+and then build it with your chosen build tool or by using ``cmake --build .``
+from the build directory.
 
 Installing and Testing (Step 4)
 ===============================
@@ -258,14 +259,15 @@
 That is all that is needed to create a basic local install of the tutorial.
 
 Run **cmake** or **cmake-gui** to configure the project and then build it
-with your chosen build tool. Build the ``install`` target by typing
-``make install`` from the command line or build the ``INSTALL`` target from
-an IDE. This will install the appropriate header files, libraries, and
-executables.
+with your chosen build tool. Run the install step by typing
+``cmake --install .`` or  from the command line, or build the ``INSTALL``
+target from an IDE. This will install the appropriate header files, libraries,
+and executables.
 
 Verify that the installed Tutorial runs. Note: The CMake variable
 ``CMAKE_INSTALL_PREFIX`` is used to determine the root of where the files will
-be installed.
+be installed. If using ``cmake --install`` a custom installation directory can
+be given via ``--prefix`` argument.
 
 Testing Support
 ---------------
@@ -596,27 +598,47 @@
 string, and ``<1:...>`` results in the content of "...".  They can also be
 nested.
 
-For example:
+A common usage of generator expressions is to conditionally add compiler
+flags, such as those as language levels or warnings. A nice pattern is
+to associate this information to an ``INTERFACE`` target allowing this
+information to propagate. Lets start by constructing an ``INTERFACE``
+target and specifying the required C++ standard level of ``11`` instead
+of using ``CMAKE_CXX_STANDARD``.
 
-.. code-block:: cmake
+So the following code:
 
-  if(HAVE_LOG AND HAVE_EXP)
-    target_compile_definitions(SqrtLibrary
-                               PRIVATE "HAVE_LOG" "HAVE_EXP")
-  endif()
+.. literalinclude:: Step10/CMakeLists.txt
+  :language: cmake
+  :start-after: project(Tutorial)
+  :end-before: # Set the version number
 
-Can be rewritten with generator expressions:
+Would be replaced with:
 
-.. code-block:: cmake
+.. literalinclude:: Step11/CMakeLists.txt
+  :language: cmake
+  :start-after: project(Tutorial)
+  :end-before: # add compiler warning flags just when building this project via
 
-  target_compile_definitions(SqrtLibrary PRIVATE
-                             "$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>"
-                             "$<$<BOOL:${HAVE_EXP}>:HAVE_EXP>"
-                            )
 
-Note that ``${HAVE_LOG}`` is evaluated at CMake configure time while
-``$<$<BOOL:${HAVE_LOG}>:HAVE_LOG>`` is evaluated at build system generation
-time.
+Next we add the desired compiler warning flags that we want for our
+project. As warning flags vary based on the compiler we use
+the ``COMPILE_LANG_AND_ID`` generator expression to control which
+flags to apply given a language and a set of compiler ids as seen
+below:
+
+.. literalinclude:: Step11/CMakeLists.txt
+  :language: cmake
+  :start-after: # the BUILD_INTERFACE genex
+  :end-before: # set the version number
+
+Looking at this we see that the warning flags are encapsulated inside a
+``BUILD_INTERFACE`` condition. This is done so that consumers of our installed
+project will not inherit our warning flags.
+
+
+**Exercise**: Modify ``MathFunctions/CMakeLists.txt`` so that
+all targets have a ``target_link_libraries()`` call to ``tutorial_compiler_flags``.
+
 
 Adding Export Configuration (Step 11)
 =====================================
diff --git a/Help/manual/cmake-buildsystem.7.rst b/Help/manual/cmake-buildsystem.7.rst
index 8cd6e68..d8142a2 100644
--- a/Help/manual/cmake-buildsystem.7.rst
+++ b/Help/manual/cmake-buildsystem.7.rst
@@ -811,6 +811,10 @@
   executable target created by the :command:`add_executable` command
   when its :prop_tgt:`ENABLE_EXPORTS` target property is set.
 
+* On AIX: the linker import file (e.g. ``.imp``) of an executable target
+  created by the :command:`add_executable` command when its
+  :prop_tgt:`ENABLE_EXPORTS` target property is set.
+
 The :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY` and :prop_tgt:`ARCHIVE_OUTPUT_NAME`
 target properties may be used to control archive output artifact locations
 and names in the build tree.
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index d7207e1..44ea1a8 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -57,6 +57,8 @@
 .. toctree::
    :maxdepth: 1
 
+   CMP0097: ExternalProject_Add with GIT_SUBMODULES "" initializes no submodules. </policy/CMP0097>
+   CMP0096: project() preserves leading zeros in version components. </policy/CMP0096>
    CMP0095: RPATH entries are properly escaped in the intermediary CMake install script. </policy/CMP0095>
 
 Policies Introduced by CMake 3.15
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 0beca82..62d23c7 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -228,6 +228,7 @@
    /prop_tgt/IMPORT_SUFFIX
    /prop_tgt/INCLUDE_DIRECTORIES
    /prop_tgt/INSTALL_NAME_DIR
+   /prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH
    /prop_tgt/INSTALL_RPATH
    /prop_tgt/INSTALL_RPATH_USE_LINK_PATH
    /prop_tgt/INTERFACE_AUTOUIC_OPTIONS
@@ -407,6 +408,7 @@
    /prop_test/REQUIRED_FILES
    /prop_test/RESOURCE_LOCK
    /prop_test/RUN_SERIAL
+   /prop_test/SKIP_REGULAR_EXPRESSION
    /prop_test/SKIP_RETURN_CODE
    /prop_test/TIMEOUT
    /prop_test/TIMEOUT_AFTER_MATCH
diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst
index 7435d9a..f233d08 100644
--- a/Help/manual/cmake-toolchains.7.rst
+++ b/Help/manual/cmake-toolchains.7.rst
@@ -399,8 +399,10 @@
   be false unless using a NDK that does not provide unified headers.
 
 :variable:`CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION`
-  Set to the version of the NDK toolchain to be selected as the compiler.
-  If not specified, the default will be the latest available GCC toolchain.
+  On NDK r19 or above, this variable must be unset or set to ``clang``.
+  On NDK r18 or below, set this to the version of the NDK toolchain to
+  be selected as the compiler.  If not specified, the default will be
+  the latest available GCC toolchain.
 
 :variable:`CMAKE_ANDROID_STL_TYPE`
   Set to specify which C++ standard library to use.  If not specified,
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index e0ce6f7..432d7fc 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -69,6 +69,7 @@
    /variable/CMAKE_MAKE_PROGRAM
    /variable/CMAKE_MATCH_COUNT
    /variable/CMAKE_MATCH_n
+   /variable/CMAKE_MESSAGE_INDENT
    /variable/CMAKE_MINIMUM_REQUIRED_VERSION
    /variable/CMAKE_MINOR_VERSION
    /variable/CMAKE_NETRC
@@ -371,6 +372,7 @@
    /variable/CMAKE_INCLUDE_CURRENT_DIR
    /variable/CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE
    /variable/CMAKE_INSTALL_NAME_DIR
+   /variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
    /variable/CMAKE_INSTALL_RPATH
    /variable/CMAKE_INSTALL_RPATH_USE_LINK_PATH
    /variable/CMAKE_INTERPROCEDURAL_OPTIMIZATION
@@ -609,7 +611,6 @@
    /variable/CPACK_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION
    /variable/CPACK_INCLUDE_TOPLEVEL_DIRECTORY
    /variable/CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
-   /variable/CPACK_INSTALL_SCRIPT
    /variable/CPACK_PACKAGING_INSTALL_PREFIX
    /variable/CPACK_SET_DESTDIR
    /variable/CPACK_WARN_ON_ABSOLUTE_INSTALL_DESTINATION
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 7b5399d..68d88e7 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -604,6 +604,12 @@
 .. note::
   Path to where ``<new>`` symbolic link will be created has to exist beforehand.
 
+``true``
+  Do nothing, with an exit code of 0.
+
+``false``
+  Do nothing, with an exit code of 1.
+
 Windows-specific Command-Line Tools
 -----------------------------------
 
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index 5773176..c6b1425 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -443,7 +443,8 @@
  Specify the name of the project to build.
 
 ``--build-makeprogram``
- Override the make program chosen by CTest with a given one.
+ Specify the explicit make program to be used by CMake when configuring and
+ building the project. Only applicable for Make and Ninja based generators.
 
 ``--build-noclean``
  Skip the make clean step.
diff --git a/Help/policy/CMP0091.rst b/Help/policy/CMP0091.rst
index 5b7c4e3..1a5878a 100644
--- a/Help/policy/CMP0091.rst
+++ b/Help/policy/CMP0091.rst
@@ -20,7 +20,9 @@
 out of the default :variable:`CMAKE_<LANG>_FLAGS_<CONFIG>` values and instead
 offer a first-class abstraction.  The :variable:`CMAKE_MSVC_RUNTIME_LIBRARY`
 variable and :prop_tgt:`MSVC_RUNTIME_LIBRARY` target property may be set to
-select the MSVC runtime library.
+select the MSVC runtime library.  If they are not set then CMake uses the
+default value ``MultiThreaded$<$<CONFIG:Debug>:Debug>DLL`` which is
+equivalent to the original flags.
 
 This policy provides compatibility with projects that have not been updated
 to be aware of the abstraction.  The policy setting takes effect as of the
diff --git a/Help/policy/CMP0096.rst b/Help/policy/CMP0096.rst
new file mode 100644
index 0000000..8eaf0f9
--- /dev/null
+++ b/Help/policy/CMP0096.rst
@@ -0,0 +1,25 @@
+CMP0096
+-------
+
+The :command:`project` command preserves leading zeros in version components.
+
+When a ``VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]`` argument is given
+to the :command:`project` command, it stores the version string in the
+``PROJECT_VERSION`` variable and stores individual integer version components
+in ``PROJECT_VERSION_{MAJOR,MINOR,PATCH,TWEAK}`` variables (see policy
+:policy:`CMP0048`).  CMake 3.15 and below dropped leading zeros from each
+component.  CMake 3.16 and higher prefer to preserve leading zeros.  This
+policy provides compatibility for projects that have not been updated to
+expect the new behavior.
+
+The ``OLD`` behavior of this policy drops leading zeros in all components,
+e.g.  such that version ``1.07.06`` becomes ``1.7.6``.  The ``NEW`` behavior
+of this policy preserves the leading zeros in all components, such that
+version ``1.07.06`` remains unchanged.
+
+This policy was introduced in CMake version 3.16.  Unlike many policies, CMake
+version |release| does *not* warn when this policy is not set and simply uses
+the ``OLD`` behavior.  Use the :command:`cmake_policy` command to set it to
+``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/policy/CMP0097.rst b/Help/policy/CMP0097.rst
new file mode 100644
index 0000000..8a5ff88
--- /dev/null
+++ b/Help/policy/CMP0097.rst
@@ -0,0 +1,23 @@
+CMP0097
+-------
+
+:command:`ExternalProject_Add` with ``GIT_SUBMODULES ""`` initializes no
+submodules.
+
+The module provides a ``GIT_SUBMODULES`` option which controls what submodules
+to initialize and update. Starting with CMake 3.16, explicitly setting
+``GIT_SUBMODULES`` to an empty string means no submodules will be initialized
+or updated.
+
+This policy provides compatibility for projects that have not been updated
+to expect the new behavior.
+
+The ``OLD`` behavior for this policy is for ``GIT_SUBMODULES`` when set to
+an empty string to initialize and update all git submodules.
+The ``New`` behavior for this policy is for ``GIT_SUBMODULES`` when set to
+an empty string to initialize and update no git submodules.
+
+This policy was introduced in CMake version 3.16.  Use the
+:command:`cmake_policy` command to set it to ``OLD`` or ``NEW`` explicitly.
+Unlike most policies, CMake version |release| does *not* warn
+when this policy is not set and simply uses ``OLD`` behavior.
diff --git a/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst b/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst
new file mode 100644
index 0000000..2c6d980
--- /dev/null
+++ b/Help/prop_test/SKIP_REGULAR_EXPRESSION.rst
@@ -0,0 +1,17 @@
+SKIP_REGULAR_EXPRESSION
+-----------------------
+
+If the output matches this regular expression the test will be marked as skipped.
+
+If set, if the output matches one of specified regular expressions,
+the test will be marked as skipped.  Example:
+
+.. code-block:: cmake
+
+  set_property(TEST mytest PROPERTY
+    SKIP_REGULAR_EXPRESSION "[^a-z]Skip" "SKIP" "Skipped"
+  )
+
+``SKIP_REGULAR_EXPRESSION`` expects a list of regular expressions.
+
+See also the :prop_test:`SKIP_RETURN_CODE` property.
diff --git a/Help/prop_test/SKIP_RETURN_CODE.rst b/Help/prop_test/SKIP_RETURN_CODE.rst
index 3d48c2f..23c4c62 100644
--- a/Help/prop_test/SKIP_RETURN_CODE.rst
+++ b/Help/prop_test/SKIP_RETURN_CODE.rst
@@ -8,3 +8,5 @@
 a return code of the process can be specified that will mark the test as
 ``Not Run`` if it is encountered. Valid values are in the range of
 0 to 255, inclusive.
+
+See also the :prop_test:`SKIP_REGULAR_EXPRESSION` property.
diff --git a/Help/prop_tgt/ENABLE_EXPORTS.rst b/Help/prop_tgt/ENABLE_EXPORTS.rst
index 581c2b9..0b1064a 100644
--- a/Help/prop_tgt/ENABLE_EXPORTS.rst
+++ b/Help/prop_tgt/ENABLE_EXPORTS.rst
@@ -7,16 +7,25 @@
 final program.  It is possible for an executable to export symbols to
 be used by loadable modules.  When this property is set to true CMake
 will allow other targets to "link" to the executable with the
-:command:`TARGET_LINK_LIBRARIES` command.  On all platforms a target-level
+:command:`target_link_libraries` command.  On all platforms a target-level
 dependency on the executable is created for targets that link to it.
-For DLL platforms an import library will be created for the exported
-symbols and then used for linking.  All Windows-based systems
-including Cygwin are DLL platforms.  For non-DLL platforms that
-require all symbols to be resolved at link time, such as macOS, the
-module will "link" to the executable using a flag like
-``-bundle_loader``.  For other non-DLL platforms the link rule is simply
-ignored since the dynamic loader will automatically bind symbols when
-the module is loaded.
+Handling of the executable on the link lines of the loadable modules
+varies by platform:
+
+* On Windows-based systems (including Cygwin) an "import library" is
+  created along with the executable to list the exported symbols.
+  Loadable modules link to the import library to get the symbols.
+
+* On macOS, loadable modules link to the executable itself using the
+  ``-bundle_loader`` flag.
+
+* On AIX, a linker "import file" is created along with the executable
+  to list the exported symbols for import when linking other targets.
+  Loadable modules link to the import file to get the symbols.
+
+* On other platforms, loadable modules are simply linked without
+  referencing the executable since the dynamic loader will
+  automatically bind symbols when the module is loaded.
 
 This property is initialized by the value of the variable
 :variable:`CMAKE_ENABLE_EXPORTS` if it is set when a target is created.
diff --git a/Help/prop_tgt/IMPORTED_IMPLIB.rst b/Help/prop_tgt/IMPORTED_IMPLIB.rst
index 77fb552..c8b6fde 100644
--- a/Help/prop_tgt/IMPORTED_IMPLIB.rst
+++ b/Help/prop_tgt/IMPORTED_IMPLIB.rst
@@ -3,5 +3,7 @@
 
 Full path to the import library for an ``IMPORTED`` target.
 
-Set this to the location of the ``.lib`` part of a Windows DLL.  Ignored
-for non-imported targets.
+Set this to the location of the ``.lib`` part of a Windows DLL, or on
+AIX set it to an import file created for executables that export symbols
+(see the :prop_tgt:`ENABLE_EXPORTS` target property).
+Ignored for non-imported targets.
diff --git a/Help/prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH.rst b/Help/prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
new file mode 100644
index 0000000..a474fc6
--- /dev/null
+++ b/Help/prop_tgt/INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
@@ -0,0 +1,10 @@
+INSTALL_REMOVE_ENVIRONMENT_RPATH
+--------------------------------
+
+Removes compiler defined rpaths durimg installation.
+
+``INSTALL_REMOVE_ENVIRONMENT_RPATH`` is a boolean that if set to ``True`` will
+remove compiler defined rpaths from the project if the user also defines rpath
+with :prop_tgt:`INSTALL_RPATH`.  This property is initialized by whether the
+value of :variable:`CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH` is set when a
+target is created.
diff --git a/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst b/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst
index 1e3f5e9..73792de 100644
--- a/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst
+++ b/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst
@@ -19,6 +19,9 @@
 selects for the target ``foo`` a multi-threaded statically-linked runtime
 library with or without debug information depending on the configuration.
 
+If this property is not set then CMake uses the default value
+``MultiThreaded$<$<CONFIG:Debug>:Debug>DLL`` to select a MSVC runtime library.
+
 .. note::
 
   This property has effect only when policy :policy:`CMP0091` is set to ``NEW``
diff --git a/Help/release/3.14.rst b/Help/release/3.14.rst
index e3a7a62..229d8dc 100644
--- a/Help/release/3.14.rst
+++ b/Help/release/3.14.rst
@@ -420,3 +420,11 @@
   from explicit use via :command:`include_directories` and
   :command:`target_include_directories` as they were in CMake 3.14.0
   through 3.14.4.
+
+3.14.6
+------
+
+* In CMake 3.14.0 through 3.14.5, the :module:`FindBISON` module
+  policy :policy:`CMP0088` ``NEW`` behavior accidentally interpreted
+  a relative path to the ``.y`` input as relative to the build tree
+  directory instead of the source tree directory.  This has been fixed.
diff --git a/Help/release/3.15.rst b/Help/release/3.15.rst
index 2cff419..4f53466 100644
--- a/Help/release/3.15.rst
+++ b/Help/release/3.15.rst
@@ -345,3 +345,20 @@
 * The :command:`file(REMOVE)` and :command:`file(REMOVE_RECURSE)` commands
   were changed to ignore empty arguments with a warning instead of treating
   them as a relative path and removing the contents of the current directory.
+
+Updates
+=======
+
+Changes made since CMake 3.15.0 include the following.
+
+3.15.1
+------
+
+* In CMake 3.15.0 support for the GNU-like ``Clang`` compiler targeting the
+  MSVC ABI implemented :variable:`CMAKE_CXX_STANDARD` values 98 and 11 using
+  the corresponding ``-std=`` flags.  However, these modes do not work with
+  the MSVC standard library.  Therefore CMake 3.15.1 passes C++14 standard
+  flags even for C++98 and C++11.  This is consistent with MSVC itself which
+  always runs in a mode aware of C++14.
+
+* Preliminary Swift support added in 3.15.0 has been updated.
diff --git a/Help/release/dev/add-install-remove-environment-rpath.rst b/Help/release/dev/add-install-remove-environment-rpath.rst
new file mode 100644
index 0000000..156106c
--- /dev/null
+++ b/Help/release/dev/add-install-remove-environment-rpath.rst
@@ -0,0 +1,6 @@
+add-install-remove-environment-rpath
+------------------------------------
+
+* A new target property, :prop_tgt:`INSTALL_REMOVE_ENVIRONMENT_RPATH`, was
+  added which removes compiler-defined rpaths from a target. This property is
+  initialized by :variable:`CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH`.
diff --git a/Help/release/dev/add_skip_regular_expression_test_property.rst b/Help/release/dev/add_skip_regular_expression_test_property.rst
new file mode 100644
index 0000000..20ef214
--- /dev/null
+++ b/Help/release/dev/add_skip_regular_expression_test_property.rst
@@ -0,0 +1,10 @@
+add_skip_regular_expression_test_property
+-----------------------------------------
+
+* A new test property, :prop_test:`SKIP_REGULAR_EXPRESSION`, has been added.
+  This property is similar to :prop_test:`FAIL_REGULAR_EXPRESSION` and
+  :prop_test:`PASS_REGULAR_EXPRESSION`, but with the same meaning as
+  :prop_test:`SKIP_RETURN_CODE`. This is useful, for example, in cases where
+  the user has no control over the return code of the test. For example, in
+  Catch2, the return value is the number of assertion failed, therefore it is
+  impossible to use it for :prop_test:`SKIP_RETURN_CODE`.
diff --git a/Help/release/dev/aix.rst b/Help/release/dev/aix.rst
new file mode 100644
index 0000000..6919358
--- /dev/null
+++ b/Help/release/dev/aix.rst
@@ -0,0 +1,20 @@
+aix
+---
+
+* On AIX, executables using the :prop_tgt:`ENABLE_EXPORTS` target property
+  now produce a linker import file with a ``.imp`` extension in addition
+  to the executable file.  Plugins (created via :command:`add_library` with
+  the ``MODULE`` option) that use :command:`target_link_libraries` to link
+  to the executable for its symbols are now linked using the import file.
+  The :command:`install(TARGETS)` command now installs the import file as
+  an ``ARCHIVE`` artifact.
+
+* On AIX, runtime linking is no longer enabled by default.  CMake provides
+  the linker enough information to resolve all symbols up front.
+  One may manually enable runtime linking for shared libraries and/or
+  loadable modules by adding ``-Wl,-G`` to their link flags
+  (e.g. in the :variable:`CMAKE_SHARED_LINKER_FLAGS` or
+  :variable:`CMAKE_MODULE_LINKER_FLAGS` variable).
+  One may manually enable runtime linking for executables by adding
+  ``-Wl,-brtl`` to their link flags (e.g. in the
+  :variable:`CMAKE_EXE_LINKER_FLAGS` variable).
diff --git a/Help/release/dev/cmake-e-true-false.rst b/Help/release/dev/cmake-e-true-false.rst
new file mode 100644
index 0000000..173fabd
--- /dev/null
+++ b/Help/release/dev/cmake-e-true-false.rst
@@ -0,0 +1,5 @@
+cmake-e-true-false
+------------------
+
+* :manual:`cmake(1)` ``-E`` now supports ``true`` and ``false`` commands, which
+  do nothing while returning exit codes of 0 and 1, respectively.
diff --git a/Help/release/dev/cmake-qch-no-version-in-filename.rst b/Help/release/dev/cmake-qch-no-version-in-filename.rst
new file mode 100644
index 0000000..3c5cb04
--- /dev/null
+++ b/Help/release/dev/cmake-qch-no-version-in-filename.rst
@@ -0,0 +1,8 @@
+cmake-qch-no-version-in-filename
+--------------------------------
+
+* The Qt Compressed Help file is now named ``CMake.qch``, which no longer
+  contains the release version in the file name.  When CMake is upgraded
+  in-place, the name and location of this file will remain constant.
+  Tools such as IDEs, help viewers, etc. should now be able to refer to this
+  file at a fixed location that remains valid across CMake upgrades.
diff --git a/Help/release/dev/cpack-install-scripts.rst b/Help/release/dev/cpack-install-scripts.rst
new file mode 100644
index 0000000..7b80d33
--- /dev/null
+++ b/Help/release/dev/cpack-install-scripts.rst
@@ -0,0 +1,5 @@
+cpack-install-scripts
+---------------------
+
+* The ``CPACK_INSTALL_SCRIPT`` variable has been deprecated in favor of the
+  new, more accurately named :variable:`CPACK_INSTALL_SCRIPTS` variable.
diff --git a/Help/release/dev/ctest-build-makeprogram-propagated-configure-pass.rst b/Help/release/dev/ctest-build-makeprogram-propagated-configure-pass.rst
new file mode 100644
index 0000000..4465de8
--- /dev/null
+++ b/Help/release/dev/ctest-build-makeprogram-propagated-configure-pass.rst
@@ -0,0 +1,6 @@
+ctest-build-makeprogram-propagated-configure-pass
+-------------------------------------------------
+
+* :manual:`ctest(1)`  ``--build-makeprogram`` now specifies the make program
+  used when configuring a project with the Ninja and Makefiles generators
+  in addition to building it.
diff --git a/Help/release/dev/external-project-support-no-git-submodules.rst b/Help/release/dev/external-project-support-no-git-submodules.rst
new file mode 100644
index 0000000..1d4be66
--- /dev/null
+++ b/Help/release/dev/external-project-support-no-git-submodules.rst
@@ -0,0 +1,6 @@
+external-project-support-no-git-submodules
+------------------------------------------
+
+* The :module:`ExternalProject` module's ``ExternalProject_Add`` command
+  has been updated so that ``GIT_SUBMODULES ""`` initializes no submodules. See
+  policy :policy:`CMP0097`.
diff --git a/Help/release/dev/global-controls-over-find-locations.rst b/Help/release/dev/global-controls-over-find-locations.rst
index 79bc869..1c0b226 100644
--- a/Help/release/dev/global-controls-over-find-locations.rst
+++ b/Help/release/dev/global-controls-over-find-locations.rst
@@ -2,8 +2,8 @@
 -----------------------------------
 
 * The :command:`find_file`, :command:`find_library`, :command:`find_path`,
-  and :command:`find_program` commands have learned to check the following
-  variables to control searching
+  :command:`find_package`, and :command:`find_program` commands have learned to
+  check the following variables to control searching
 
   * :variable:`CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH` - Controls the searching
     the cmake-specific environment variables.
diff --git a/Help/release/dev/message-indent.rst b/Help/release/dev/message-indent.rst
new file mode 100644
index 0000000..b170708
--- /dev/null
+++ b/Help/release/dev/message-indent.rst
@@ -0,0 +1,5 @@
+message-indent
+--------------
+
+* The :command:`message` command learned indentation control with the new
+  :variable:`CMAKE_MESSAGE_INDENT` variable.
diff --git a/Help/release/dev/project-version-0.rst b/Help/release/dev/project-version-0.rst
new file mode 100644
index 0000000..6525522
--- /dev/null
+++ b/Help/release/dev/project-version-0.rst
@@ -0,0 +1,5 @@
+project-version-0
+-----------------
+
+* The :command:`project` no longer strips leading zeros in version components.
+  See policy :policy:`CMP0096`.
diff --git a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst
index 5ae55d1..22808e3 100644
--- a/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst
+++ b/Help/variable/CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION.rst
@@ -3,7 +3,11 @@
 
 When :ref:`Cross Compiling for Android with the NDK`, this variable
 may be set to specify the version of the toolchain to be used
-as the compiler.  The variable must be set to one of these forms:
+as the compiler.
+
+On NDK r19 or above, this variable must be unset or set to ``clang``.
+
+On NDK r18 or below, this variable must be set to one of these forms:
 
 * ``<major>.<minor>``: GCC of specified version
 * ``clang<major>.<minor>``: Clang of specified version
diff --git a/Help/variable/CMAKE_ENABLE_EXPORTS.rst b/Help/variable/CMAKE_ENABLE_EXPORTS.rst
index 7ec4d63..8848da1 100644
--- a/Help/variable/CMAKE_ENABLE_EXPORTS.rst
+++ b/Help/variable/CMAKE_ENABLE_EXPORTS.rst
@@ -1,22 +1,8 @@
 CMAKE_ENABLE_EXPORTS
 --------------------
 
-Specify whether an executable exports symbols for loadable modules.
+Specify whether executables export symbols for loadable modules.
 
-Normally an executable does not export any symbols because it is the
-final program.  It is possible for an executable to export symbols to
-be used by loadable modules.  When this property is set to true CMake
-will allow other targets to ``link`` to the executable with the
-:command:`TARGET_LINK_LIBRARIES` command.  On all platforms a target-level
-dependency on the executable is created for targets that link to it.
-For DLL platforms an import library will be created for the exported
-symbols and then used for linking.  All Windows-based systems
-including Cygwin are DLL platforms.  For non-DLL platforms that
-require all symbols to be resolved at link time, such as macOS, the
-module will ``link`` to the executable using a flag like
-``-bundle_loader``.  For other non-DLL platforms the link rule is simply
-ignored since the dynamic loader will automatically bind symbols when
-the module is loaded.
-
-This variable is used to initialize the target property
-:prop_tgt:`ENABLE_EXPORTS` for executable targets.
+This variable is used to initialize the :prop_tgt:`ENABLE_EXPORTS` target
+property for executable targets when they are created by calls to the
+:command:`add_executable` command.  See the property documentation for details.
diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst
index 33514a0..2db5081 100644
--- a/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH.rst
@@ -3,7 +3,7 @@
 
 Controls the searching the cmake-specific environment variables by the
 :command:`find_program`, :command:`find_library`, :command:`find_file`,
-and :command:`find_path` commands.
+:command:`find_path`, and command:`find_package` commands.
 This is useful in cross-compiling environments.
 
 By default this variable is not set, which is equivalent to it having
diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst
index cefc645..4ca7ad1 100644
--- a/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_CMAKE_PATH.rst
@@ -3,7 +3,7 @@
 
 Controls the searching the cmake-specific cache variables by the
 :command:`find_program`, :command:`find_library`, :command:`find_file`,
-and :command:`find_path` commands.
+:command:`find_path`, and command:`find_package` commands.
 This is useful in cross-compiling environments.
 
 By default this variable is not set, which is equivalent to it having
diff --git a/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst b/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst
index 2aa544d..d3259ae 100644
--- a/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_CMAKE_SYSTEM_PATH.rst
@@ -3,7 +3,7 @@
 
 Controls the searching cmake platform specific variables by the
 :command:`find_program`, :command:`find_library`, :command:`find_file`,
-and :command:`find_path` commands.
+:command:`find_path`, and command:`find_package` commands.
 This is useful in cross-compiling environments.
 
 By default this variable is not set, which is equivalent to it having
diff --git a/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst b/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst
index 899e62e..e17fdcc 100644
--- a/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_PACKAGE_ROOT_PATH.rst
@@ -3,7 +3,7 @@
 
 Controls the searching of :variable:`<PackageName>_ROOT` variables by the
 :command:`find_program`, :command:`find_library`, :command:`find_file`,
-and :command:`find_path` commands.
+:command:`find_path`, and command:`find_package` commands.
 This is useful in cross-compiling environments.
 
 By default this variable is not set, which is equivalent to it having
diff --git a/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst b/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst
index 604c710..71432f6 100644
--- a/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst
+++ b/Help/variable/CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH.rst
@@ -3,7 +3,7 @@
 
 Controls the searching the standard system environment variables by the
 :command:`find_program`, :command:`find_library`, :command:`find_file`,
-and :command:`find_path` commands.
+:command:`find_path`, and command:`find_package` commands.
 This is useful in cross-compiling environments.
 
 By default this variable is not set, which is equivalent to it having
diff --git a/Help/variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH.rst b/Help/variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
new file mode 100644
index 0000000..19ae5f3
--- /dev/null
+++ b/Help/variable/CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH.rst
@@ -0,0 +1,9 @@
+CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH
+--------------------------------------
+
+Removes compiler defined rpaths durimg installation.
+
+``CMAKE_INSTALL_REMOVE_ENVIRONMENT_RPATH`` is a boolean that if set to ``true``
+removes compiler defined rpaths from the project if the user also defines rpath
+with :prop_tgt:`INSTALL_RPATH`. This is used to initialize the target property
+:prop_tgt:`INSTALL_REMOVE_ENVIRONMENT_RPATH` for all targets.
diff --git a/Help/variable/CMAKE_MESSAGE_INDENT.rst b/Help/variable/CMAKE_MESSAGE_INDENT.rst
new file mode 100644
index 0000000..f7975ab
--- /dev/null
+++ b/Help/variable/CMAKE_MESSAGE_INDENT.rst
@@ -0,0 +1,30 @@
+CMAKE_MESSAGE_INDENT
+--------------------
+
+The :command:`message` command joins the strings from this list and for
+log levels of ``NOTICE`` and below, it prepends the resultant string to
+each line of the message.
+
+Example:
+
+.. code-block:: cmake
+
+  list(APPEND listVar one two three)
+
+  message(VERBOSE [[Collected items in the "listVar":]])
+  list(APPEND CMAKE_MESSAGE_INDENT "  ")
+
+  foreach(item IN LISTS listVar)
+    message(VERBOSE ${item})
+  endforeach()
+
+  list(POP_BACK CMAKE_MESSAGE_INDENT)
+  message(VERBOSE "No more indent")
+
+Which results in the following output:
+
+  -- Collected items in the "listVar":
+  --   one
+  --   two
+  --   tree
+  -- No more indent
diff --git a/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst b/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst
index 6ed68c9..8b54e7e 100644
--- a/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst
+++ b/Help/variable/CMAKE_MSVC_RUNTIME_LIBRARY.rst
@@ -20,6 +20,11 @@
 selects for all following targets a multi-threaded statically-linked runtime
 library with or without debug information depending on the configuration.
 
+If this variable is not set then the :prop_tgt:`MSVC_RUNTIME_LIBRARY` target
+property will not be set automatically.  If that property is not set then
+CMake uses the default value ``MultiThreaded$<$<CONFIG:Debug>:Debug>DLL``
+to select a MSVC runtime library.
+
 .. note::
 
   This variable has effect only when policy :policy:`CMP0091` is set to ``NEW``
diff --git a/Help/variable/CPACK_INSTALL_SCRIPT.rst b/Help/variable/CPACK_INSTALL_SCRIPT.rst
deleted file mode 100644
index 12a48a4..0000000
--- a/Help/variable/CPACK_INSTALL_SCRIPT.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-CPACK_INSTALL_SCRIPT
---------------------
-
-Extra CMake script provided by the user.
-
-If set this CMake script will be executed by CPack during its local
-[CPack-private] installation which is done right before packaging the
-files.  The script is not called by e.g.: ``make install``.
diff --git a/Modules/CMakeDetermineCSharpCompiler.cmake b/Modules/CMakeDetermineCSharpCompiler.cmake
index dab9414..da860a8 100644
--- a/Modules/CMakeDetermineCSharpCompiler.cmake
+++ b/Modules/CMakeDetermineCSharpCompiler.cmake
@@ -18,7 +18,6 @@
   set(CMAKE_CSharp_COMPILER_ID_RUN 1)
 
   # Try to identify the compiler.
-  set(CMAKE_CSharp_COMPILER_ID_STRINGS_PARAMETERS ENCODING UTF-16LE)
   set(CMAKE_CSharp_COMPILER_ID)
   include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
   CMAKE_DETERMINE_COMPILER_ID(CSharp CSFLAGS CMakeCSharpCompilerId.cs)
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 6083358..1914f52 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -640,10 +640,14 @@
     set(ARCHITECTURE_ID)
     set(SIMULATE_ID)
     set(SIMULATE_VERSION)
-    file(STRINGS ${file}
-      CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 38
-      ${CMAKE_${lang}_COMPILER_ID_STRINGS_PARAMETERS}
-      REGEX ".?I.?N.?F.?O.?:.?[A-Za-z0-9_]+\\[[^]]*\\]")
+    foreach(encoding "" "ENCODING;UTF-16LE" "ENCODING;UTF-16BE")
+      file(STRINGS "${file}" CMAKE_${lang}_COMPILER_ID_STRINGS
+        LIMIT_COUNT 38 ${encoding}
+        REGEX ".?I.?N.?F.?O.?:.?[A-Za-z0-9_]+\\[[^]]*\\]")
+      if(NOT CMAKE_${lang}_COMPILER_ID_STRINGS STREQUAL "")
+        break()
+      endif()
+    endforeach()
     set(COMPILER_ID_TWICE)
     # With the IAR Compiler, some strings are found twice, first time as incomplete
     # list like "?<Constant "INFO:compiler[IAR]">".  Remove the incomplete copies.
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index 0f84cce..58b0813 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -18,9 +18,18 @@
 endif()
 
 set(CMAKE_INCLUDE_FLAG_Swift "-I ")
+if(NOT CMAKE_SYSTEM_NAME STREQUAL Windows AND NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
+  set(CMAKE_SHARED_LIBRARY_SONAME_Swift_FLAG "-Xlinker -soname -Xlinker ")
+endif()
 
 set(CMAKE_Swift_COMPILE_OPTIONS_TARGET "-target ")
-set(CMAKE_Swift_COMPILER_ARG1 -frontend)
+set(CMAKE_Swift_COMPILE_OPTIONS_EXTERNAL_TOOLCHAIN "-tools-directory ")
+# NOTE(compnerd) the `-sdk` support is not yet ready in the compiler; when that
+# is fully working, we should be able to enable this.
+# set(CMAKE_Swift_COMPILE_OPTIONS_SYSROOT "-sdk ")
+# NOTE(compnerd) do not setup `-frontend` as we use the compiler as the driver
+# during the link phase and use that to drive the compilation
+set(CMAKE_Swift_COMPILER_ARG1 "")
 set(CMAKE_Swift_DEFINE_FLAG -D)
 set(CMAKE_Swift_FRAMEWORK_SEARCH_FLAG "-F ")
 set(CMAKE_Swift_LIBRARY_PATH_FLAG "-L ")
@@ -54,11 +63,7 @@
 endif()
 
 if(NOT CMAKE_Swift_CREATE_SHARED_LIBRARY)
-  if(CMAKE_Swift_COMPILER_TARGET)
-    set(CMAKE_Swift_CREATE_SHARED_LIBRARY "${CMAKE_Swift_COMPILER} -target <CMAKE_Swift_COMPILER_TARGET> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
-  else()
-    set(CMAKE_Swift_CREATE_SHARED_LIBRARY "${CMAKE_Swift_COMPILER} -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
-  endif()
+  set(CMAKE_Swift_CREATE_SHARED_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <SONAME_FLAG> <TARGET_SONAME> <LINK_LIBRARIES>")
 endif()
 
 if(NOT CMAKE_Swift_CREATE_SHARED_MODULE)
@@ -66,19 +71,11 @@
 endif()
 
 if(NOT CMAKE_Swift_LINK_EXECUTABLE)
-  if(CMAKE_Swift_COMPILER_TARGET)
-    set(CMAKE_Swift_LINK_EXECUTABLE "${CMAKE_Swift_COMPILER} -target <CMAKE_Swift_COMPILER_TARGET> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
-  else()
-    set(CMAKE_Swift_LINK_EXECUTABLE "${CMAKE_Swift_COMPILER} -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
-  endif()
+  set(CMAKE_Swift_LINK_EXECUTABLE "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-executable -o <TARGET> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
 endif()
 
 if(NOT CMAKE_Swift_CREATE_STATIC_LIBRARY)
-  if(CMAKE_Swift_COMPILER_TARGET)
-    set(CMAKE_Swift_CREATE_STATIC_LIBRARY "${CMAKE_Swift_COMPILER} -target <CMAKE_Swift_COMPILER_TARGET> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
-  else()
-    set(CMAKE_Swift_CREATE_STATIC_LIBRARY "${CMAKE_Swift_COMPILER} -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
-  endif()
+  set(CMAKE_Swift_CREATE_STATIC_LIBRARY "<CMAKE_Swift_COMPILER> -output-file-map <SWIFT_OUTPUT_FILE_MAP> -incremental -num-threads ${CMAKE_Swift_NUM_THREADS} -emit-library -static -o <TARGET> -module-name <SWIFT_MODULE_NAME> -module-link-name <SWIFT_LIBRARY_NAME> -emit-module -emit-module-path <SWIFT_MODULE> -emit-dependencies <DEFINES> <FLAGS> <INCLUDES> <SWIFT_SOURCES> <LINK_FLAGS> <LINK_LIBRARIES>")
 
   set(CMAKE_Swift_ARCHIVE_CREATE "<CMAKE_AR> crs <TARGET> <OBJECTS>")
   set(CMAKE_Swift_ARCHIVE_FINISH "")
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index c9008db..8a6a712 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -325,7 +325,21 @@
 
 .. variable:: CPACK_INSTALL_COMMANDS
 
-  Extra commands to install components.
+  Extra commands to install components.  The environment variable
+  ``CMAKE_INSTALL_PREFIX`` is set to the temporary install directory
+  during execution.
+
+.. variable:: CPACK_INSTALL_SCRIPTS
+
+  Extra CMake scripts executed by CPack during its local staging
+  installation, which is done right before packaging the files.
+  The scripts are not called by a standalone install (e.g.: ``make install``).
+  For every script, the following variables will be set:
+  :variable:`CMAKE_CURRENT_SOURCE_DIR`, :variable:`CMAKE_CURRENT_BINARY_DIR`
+  and :variable:`CMAKE_INSTALL_PREFIX` (which is set to the staging install
+  directory).  The singular form ``CMAKE_INSTALL_SCRIPT`` is supported as
+  an alternative variable for historical reasons, but its value is ignored if
+  ``CMAKE_INSTALL_SCRIPTS`` is set and a warning will be issued.
 
 .. variable:: CPACK_INSTALLED_DIRECTORIES
 
diff --git a/Modules/Compiler/Clang-CXX.cmake b/Modules/Compiler/Clang-CXX.cmake
index 17f3917..61709f8 100644
--- a/Modules/Compiler/Clang-CXX.cmake
+++ b/Modules/Compiler/Clang-CXX.cmake
@@ -58,6 +58,13 @@
   unset(_clang_version_std17)
 
   if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC")
+    # The MSVC standard library requires C++14, and MSVC itself has no
+    # notion of operating in a mode not aware of at least that standard.
+    set(CMAKE_CXX98_STANDARD_COMPILE_OPTION "-std=c++14")
+    set(CMAKE_CXX98_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+    set(CMAKE_CXX11_STANDARD_COMPILE_OPTION "-std=c++14")
+    set(CMAKE_CXX11_EXTENSION_COMPILE_OPTION "-std=gnu++14")
+
     # This clang++ is missing some features because of MSVC compatibility.
     unset(CMAKE_CXX11_STANDARD__HAS_FULL_SUPPORT)
     unset(CMAKE_CXX14_STANDARD__HAS_FULL_SUPPORT)
diff --git a/Modules/Compiler/XL.cmake b/Modules/Compiler/XL.cmake
index a9cec11..fc71ab4 100644
--- a/Modules/Compiler/XL.cmake
+++ b/Modules/Compiler/XL.cmake
@@ -18,6 +18,8 @@
   set(CMAKE_${lang}_RESPONSE_FILE_FLAG "-qoptfile=")
   set(CMAKE_${lang}_RESPONSE_FILE_LINK_FLAG "-qoptfile=")
 
+  set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-qmkshrobj")
+
   set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
   set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",")
 
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 20b37d2..14fc231 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -261,7 +261,9 @@
 
       ``GIT_SUBMODULES <module>...``
         Specific git submodules that should also be updated. If this option is
-        not provided, all git submodules will be updated.
+        not provided, all git submodules will be updated. When :policy:`CMP0097`
+        is set to ``NEW`` if this value is set to an empty string then no submodules
+        are initialized or updated.
 
       ``GIT_SHALLOW <bool>``
         When this option is enabled, the ``git clone`` operation will be given
@@ -1016,6 +1018,9 @@
       endif()
     else()
       set(key "${arg}")
+      if(key MATCHES GIT)
+       get_property(have_key TARGET ${name} PROPERTY ${ns}${key} SET)
+      endif()
     endif()
   endforeach()
 endfunction()
@@ -1060,7 +1065,7 @@
   "ExternalProject module."
   )
 
-function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_remote_name git_submodules git_shallow git_progress git_config src_name work_dir gitclone_infofile gitclone_stampfile tls_verify)
+function(_ep_write_gitclone_script script_filename source_dir git_EXECUTABLE git_repository git_tag git_remote_name init_submodules git_submodules git_shallow git_progress git_config src_name work_dir gitclone_infofile gitclone_stampfile tls_verify)
   if(NOT GIT_VERSION_STRING VERSION_LESS 1.8.5)
     # Use `git checkout <tree-ish> --` to avoid ambiguity with a local path.
     set(git_checkout_explicit-- "--")
@@ -1145,11 +1150,14 @@
   message(FATAL_ERROR \"Failed to checkout tag: '${git_tag}'\")
 endif()
 
-execute_process(
-  COMMAND \"${git_EXECUTABLE}\" ${git_options} submodule update --recursive --init ${git_submodules}
-  WORKING_DIRECTORY \"${work_dir}/${src_name}\"
-  RESULT_VARIABLE error_code
-  )
+set(init_submodules ${init_submodules})
+if(init_submodules)
+  execute_process(
+    COMMAND \"${git_EXECUTABLE}\" ${git_options} submodule update --recursive --init ${git_submodules}
+    WORKING_DIRECTORY \"${work_dir}/${src_name}\"
+    RESULT_VARIABLE error_code
+    )
+endif()
 if(error_code)
   message(FATAL_ERROR \"Failed to update submodules in: '${work_dir}/${src_name}'\")
 endif()
@@ -1226,7 +1234,7 @@
 endfunction()
 
 
-function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name git_submodules git_repository work_dir)
+function(_ep_write_gitupdate_script script_filename git_EXECUTABLE git_tag git_remote_name init_submodules git_submodules git_repository work_dir)
   if("${git_tag}" STREQUAL "")
     message(FATAL_ERROR "Tag for git checkout should not be empty.")
   endif()
@@ -1383,11 +1391,14 @@
     endif()
   endif()
 
-  execute_process(
-    COMMAND \"${git_EXECUTABLE}\" submodule update --recursive --init ${git_submodules}
-    WORKING_DIRECTORY \"${work_dir}/${src_name}\"
-    RESULT_VARIABLE error_code
-    )
+  set(init_submodules ${init_submodules})
+  if(init_submodules)
+    execute_process(
+      COMMAND \"${git_EXECUTABLE}\" submodule update --recursive --init ${git_submodules}
+      WORKING_DIRECTORY \"${work_dir}/${src_name}\"
+      RESULT_VARIABLE error_code
+      )
+  endif()
   if(error_code)
     message(FATAL_ERROR \"Failed to update submodules in: '${work_dir}/${src_name}'\")
   endif()
@@ -1972,7 +1983,7 @@
     set(stderr_log "${logbase}-err.log")
   endif()
   set(code "
-cmake_minimum_required(VERSION 3.13)
+cmake_minimum_required(VERSION 3.15)
 ${code_cygpath_make}
 set(command \"${command}\")
 set(log_merged \"${log_merged}\")
@@ -2420,7 +2431,15 @@
     if(NOT git_tag)
       set(git_tag "master")
     endif()
-    get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES)
+
+    set(git_init_submodules TRUE)
+    get_property(git_submodules_set TARGET ${name} PROPERTY _EP_GIT_SUBMODULES SET)
+    if(git_submodules_set)
+      get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES)
+      if(git_submodules  STREQUAL "" AND _EP_CMP0097 STREQUAL "NEW")
+        set(git_init_submodules FALSE)
+      endif()
+    endif()
 
     get_property(git_remote_name TARGET ${name} PROPERTY _EP_GIT_REMOTE_NAME)
     if(NOT git_remote_name)
@@ -2458,7 +2477,7 @@
     # The script will delete the source directory and then call git clone.
     #
     _ep_write_gitclone_script(${tmp_dir}/${name}-gitclone.cmake ${source_dir}
-      ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${git_remote_name} "${git_submodules}" "${git_shallow}" "${git_progress}" "${git_config}" ${src_name} ${work_dir}
+      ${GIT_EXECUTABLE} ${git_repository} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules}" "${git_shallow}" "${git_progress}" "${git_config}" ${src_name} ${work_dir}
       ${stamp_dir}/${name}-gitinfo.txt ${stamp_dir}/${name}-gitclone-lastrun.txt "${tls_verify}"
       )
     set(comment "Performing download step (git clone) for '${name}'")
@@ -2723,9 +2742,18 @@
     if(NOT git_remote_name)
       set(git_remote_name "origin")
     endif()
-    get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES)
+
+    set(git_init_submodules TRUE)
+    get_property(git_submodules_set TARGET ${name} PROPERTY _EP_GIT_SUBMODULES SET)
+    if(git_submodules_set)
+      get_property(git_submodules TARGET ${name} PROPERTY _EP_GIT_SUBMODULES)
+      if(git_submodules  STREQUAL "" AND _EP_CMP0097 STREQUAL "NEW")
+        set(git_init_submodules FALSE)
+      endif()
+    endif()
+
     _ep_write_gitupdate_script(${tmp_dir}/${name}-gitupdate.cmake
-      ${GIT_EXECUTABLE} ${git_tag} ${git_remote_name} "${git_submodules}" ${git_repository} ${work_dir}
+      ${GIT_EXECUTABLE} ${git_tag} ${git_remote_name} ${git_init_submodules} "${git_submodules}" ${git_repository} ${work_dir}
       )
     set(cmd ${CMAKE_COMMAND} -P ${tmp_dir}/${name}-gitupdate.cmake)
     set(always 1)
@@ -3138,6 +3166,10 @@
 
 
 function(ExternalProject_Add name)
+  cmake_policy(GET CMP0097 _EP_CMP0097
+    PARENT_SCOPE # undocumented, do not use outside of CMake
+    )
+
   _ep_get_configuration_subdir_suffix(cfgdir)
 
   # Add a custom target for the external project.
diff --git a/Modules/FindBISON.cmake b/Modules/FindBISON.cmake
index e75981c..6b5828e 100644
--- a/Modules/FindBISON.cmake
+++ b/Modules/FindBISON.cmake
@@ -257,15 +257,19 @@
         PARENT_SCOPE # undocumented, do not use outside of CMake
         )
       set(_BISON_WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+      set(_BisonInput "${BisonInput}")
       if("x${_BISON_CMP0088}x" STREQUAL "xNEWx")
         set(_BISON_WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
+        if(NOT IS_ABSOLUTE "${_BisonInput}")
+          set(_BisonInput "${CMAKE_CURRENT_SOURCE_DIR}/${_BisonInput}")
+        endif()
       endif()
       unset(_BISON_CMP0088)
 
       add_custom_command(OUTPUT ${BISON_TARGET_outputs}
-        COMMAND ${BISON_EXECUTABLE} ${BISON_TARGET_cmdopt} -o ${BisonOutput} ${BisonInput}
+        COMMAND ${BISON_EXECUTABLE} ${BISON_TARGET_cmdopt} -o ${BisonOutput} ${_BisonInput}
         VERBATIM
-        DEPENDS ${BisonInput}
+        DEPENDS ${_BisonInput}
         COMMENT "[BISON][${Name}] Building parser with bison ${BISON_VERSION}"
         WORKING_DIRECTORY ${_BISON_WORKING_DIRECTORY})
 
@@ -273,12 +277,14 @@
 
       # define target variables
       set(BISON_${Name}_DEFINED TRUE)
-      set(BISON_${Name}_INPUT ${BisonInput})
+      set(BISON_${Name}_INPUT ${_BisonInput})
       set(BISON_${Name}_OUTPUTS ${BISON_TARGET_outputs} ${BISON_TARGET_extraoutputs})
       set(BISON_${Name}_COMPILE_FLAGS ${BISON_TARGET_cmdopt})
       set(BISON_${Name}_OUTPUT_SOURCE "${BisonOutput}")
       set(BISON_${Name}_OUTPUT_HEADER "${BISON_TARGET_output_header}")
 
+      unset(_BisonInput)
+
     endif()
   endmacro()
   #
diff --git a/Modules/FindMPI.cmake b/Modules/FindMPI.cmake
index 2ff6afe..a79758f 100644
--- a/Modules/FindMPI.cmake
+++ b/Modules/FindMPI.cmake
@@ -1147,9 +1147,7 @@
   set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_COMPILE_DEFINITIONS "${MPI_${LANG}_COMPILE_DEFINITIONS}")
 
   if(MPI_${LANG}_LINK_FLAGS)
-    separate_arguments(_MPI_${LANG}_LINK_FLAGS NATIVE_COMMAND "${MPI_${LANG}_LINK_FLAGS}")
-    set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_LINK_OPTIONS "${_MPI_${LANG}_LINK_FLAGS}")
-    unset(_MPI_${LANG}_LINK_FLAGS)
+    set_property(TARGET MPI::MPI_${LANG} PROPERTY INTERFACE_LINK_OPTIONS "SHELL:${MPI_${LANG}_LINK_FLAGS}")
   endif()
   # If the compiler links MPI implicitly, no libraries will be found as they're contained within
   # CMAKE_<LANG>_IMPLICIT_LINK_LIBRARIES already.
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index 03f1500..c8cae2e 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -609,14 +609,23 @@
     set(devnull INPUT_FILE NUL)
   endif()
 
+  if(WIN32)
+    # this environment variable is used to determine the arch on Windows
+    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+      set(ENV{MATLAB_ARCH} "win64")
+    else()
+      set(ENV{MATLAB_ARCH} "win32")
+    endif()
+  endif()
+
   # this is the preferred way. If this does not work properly (eg. MCR on Windows), then we use our own knowledge
   execute_process(
     COMMAND ${Matlab_MEXEXTENSIONS_PROG}
     OUTPUT_VARIABLE _matlab_mex_extension
-    #RESULT_VARIABLE _matlab_mex_extension_call
     ERROR_VARIABLE _matlab_mex_extension_error
     OUTPUT_STRIP_TRAILING_WHITESPACE
     ${devnull})
+  unset(ENV{MATLAB_ARCH})
 
   if(_matlab_mex_extension_error)
     if(WIN32)
@@ -631,7 +640,7 @@
 
   string(STRIP "${_matlab_mex_extension}"  _matlab_mex_extension)
   if(MATLAB_FIND_DEBUG)
-    message(STATUS "[MATLAB] '${Matlab_MEXEXTENSIONS_PROG}' : returned '${_matlab_mex_extension_call}', determined extension '${_matlab_mex_extension}' and error string is '${_matlab_mex_extension_error}'")
+    message(STATUS "[MATLAB] '${Matlab_MEXEXTENSIONS_PROG}' : determined extension '${_matlab_mex_extension}' and error string is '${_matlab_mex_extension_error}'")
   endif()
 
   unset(Matlab_MEXEXTENSIONS_PROG CACHE)
@@ -1043,14 +1052,9 @@
         set(_link_flags "${_link_flags} /EXPORT:mexfilerequiredapiversion")
       endif()
 
-      if(Matlab_HAS_CPP_API)
-        set(_link_flags "${_link_flags} /EXPORT:mexCreateMexFunction /EXPORT:mexDestroyMexFunction /EXPORT:mexFunctionAdapter")
-        #TODO: Is this necessary?
-      endif()
-
       set_property(TARGET ${${prefix}_NAME} APPEND PROPERTY LINK_FLAGS ${_link_flags})
 
-    endif() # TODO: what if there's a different compiler on Windows?
+    endif() # No other compiler currently supported on Windows.
 
     set_target_properties(${${prefix}_NAME}
       PROPERTIES
@@ -1533,7 +1537,9 @@
   message(STATUS "[MATLAB] Current version is ${Matlab_VERSION_STRING} located ${Matlab_ROOT_DIR}")
 endif()
 
-if(NOT ${Matlab_VERSION_STRING} VERSION_LESS "9.4") # MATLAB 9.4 (R2018a) and newer have a new C++ API
+# MATLAB 9.4 (R2018a) and newer have a new C++ API
+# This API pulls additional required libraries.
+if(NOT ${Matlab_VERSION_STRING} VERSION_LESS "9.4")
   set(Matlab_HAS_CPP_API 1)
 endif()
 
@@ -1619,6 +1625,10 @@
 
 set(_matlab_required_variables)
 
+# Order is as follow:
+# - unconditionally required libraries/headers first
+# - then library components
+# - then program components
 
 # the MEX library/header are required
 find_path(
@@ -1644,34 +1654,6 @@
 # the matlab root is required
 list(APPEND _matlab_required_variables Matlab_ROOT_DIR)
 
-# component Mex Compiler
-if("MEX_COMPILER" IN_LIST Matlab_FIND_COMPONENTS)
-  find_program(
-    Matlab_MEX_COMPILER
-    "mex"
-    PATHS ${Matlab_BINARIES_DIR}
-    DOC "Matlab MEX compiler"
-    NO_DEFAULT_PATH
-  )
-  if(Matlab_MEX_COMPILER)
-    set(Matlab_MEX_COMPILER_FOUND TRUE)
-  endif()
-endif()
-
-# component Matlab program
-if("MAIN_PROGRAM" IN_LIST Matlab_FIND_COMPONENTS)
-  find_program(
-    Matlab_MAIN_PROGRAM
-    matlab
-    PATHS ${Matlab_ROOT_DIR} ${Matlab_ROOT_DIR}/bin
-    DOC "Matlab main program"
-    NO_DEFAULT_PATH
-  )
-  if(Matlab_MAIN_PROGRAM)
-    set(Matlab_MAIN_PROGRAM_FOUND TRUE)
-  endif()
-endif()
-
 # The MX library is required
 _Matlab_find_library(
   ${_matlab_lib_prefix_for_search}
@@ -1685,70 +1667,6 @@
   set(Matlab_MX_LIBRARY_FOUND TRUE)
 endif()
 
-# Component ENG library
-list(FIND Matlab_FIND_COMPONENTS ENG_LIBRARY _matlab_find_eng)
-if(_matlab_find_eng GREATER -1)
-  _Matlab_find_library(
-    ${_matlab_lib_prefix_for_search}
-    Matlab_ENG_LIBRARY
-    eng
-    PATHS ${_matlab_lib_dir_for_search}
-    NO_DEFAULT_PATH
-  )
-  if(Matlab_ENG_LIBRARY)
-    set(Matlab_ENG_LIBRARY_FOUND TRUE)
-  endif()
-endif()
-unset(_matlab_find_eng)
-
-# Component MAT library
-list(FIND Matlab_FIND_COMPONENTS MAT_LIBRARY _matlab_find_mat)
-if(_matlab_find_mat GREATER -1)
-  _Matlab_find_library(
-    ${_matlab_lib_prefix_for_search}
-    Matlab_MAT_LIBRARY
-    mat
-    PATHS ${_matlab_lib_dir_for_search}
-    NO_DEFAULT_PATH
-  )
-  if(Matlab_MAT_LIBRARY)
-    set(Matlab_MAT_LIBRARY_FOUND TRUE)
-  endif()
-endif()
-unset(_matlab_find_mat)
-
-# Component Simulink
-list(FIND Matlab_FIND_COMPONENTS SIMULINK _matlab_find_simulink)
-if(_matlab_find_simulink GREATER -1)
-  find_path(
-    Matlab_SIMULINK_INCLUDE_DIR
-    simstruc.h
-    PATHS "${Matlab_ROOT_DIR}/simulink/include"
-    NO_DEFAULT_PATH
-    )
-  if(Matlab_SIMULINK_INCLUDE_DIR)
-    set(Matlab_SIMULINK_FOUND TRUE)
-    list(APPEND Matlab_INCLUDE_DIRS "${Matlab_SIMULINK_INCLUDE_DIR}")
-  endif()
-endif()
-unset(_matlab_find_simulink)
-
-# component MCC Compiler
-list(FIND Matlab_FIND_COMPONENTS MCC_COMPILER _matlab_find_mcc_compiler)
-if(_matlab_find_mcc_compiler GREATER -1)
-  find_program(
-    Matlab_MCC_COMPILER
-    "mcc"
-    PATHS ${Matlab_BINARIES_DIR}
-    DOC "Matlab MCC compiler"
-    NO_DEFAULT_PATH
-  )
-  if(Matlab_MCC_COMPILER)
-    set(Matlab_MCC_COMPILER_FOUND TRUE)
-  endif()
-endif()
-unset(_matlab_find_mcc_compiler)
-
 if(Matlab_HAS_CPP_API)
 
   # The MatlabEngine library is required for R2018a+
@@ -1781,7 +1699,89 @@
 
 endif()
 
-unset(_matlab_lib_dir_for_search)
+# Component ENG library
+if("ENG_LIBRARY" IN_LIST Matlab_FIND_COMPONENTS)
+  _Matlab_find_library(
+    ${_matlab_lib_prefix_for_search}
+    Matlab_ENG_LIBRARY
+    eng
+    PATHS ${_matlab_lib_dir_for_search}
+    NO_DEFAULT_PATH
+  )
+  if(Matlab_ENG_LIBRARY)
+    set(Matlab_ENG_LIBRARY_FOUND TRUE)
+  endif()
+endif()
+
+# Component MAT library
+if("MAT_LIBRARY" IN_LIST Matlab_FIND_COMPONENTS)
+  _Matlab_find_library(
+    ${_matlab_lib_prefix_for_search}
+    Matlab_MAT_LIBRARY
+    mat
+    PATHS ${_matlab_lib_dir_for_search}
+    NO_DEFAULT_PATH
+  )
+  if(Matlab_MAT_LIBRARY)
+    set(Matlab_MAT_LIBRARY_FOUND TRUE)
+  endif()
+endif()
+
+# Component Simulink
+if("SIMULINK" IN_LIST Matlab_FIND_COMPONENTS)
+  find_path(
+    Matlab_SIMULINK_INCLUDE_DIR
+    simstruc.h
+    PATHS "${Matlab_ROOT_DIR}/simulink/include"
+    NO_DEFAULT_PATH
+    )
+  if(Matlab_SIMULINK_INCLUDE_DIR)
+    set(Matlab_SIMULINK_FOUND TRUE)
+    list(APPEND Matlab_INCLUDE_DIRS "${Matlab_SIMULINK_INCLUDE_DIR}")
+  endif()
+endif()
+
+# component Matlab program
+if("MAIN_PROGRAM" IN_LIST Matlab_FIND_COMPONENTS)
+  find_program(
+    Matlab_MAIN_PROGRAM
+    matlab
+    PATHS ${Matlab_ROOT_DIR} ${Matlab_ROOT_DIR}/bin
+    DOC "Matlab main program"
+    NO_DEFAULT_PATH
+  )
+  if(Matlab_MAIN_PROGRAM)
+    set(Matlab_MAIN_PROGRAM_FOUND TRUE)
+  endif()
+endif()
+
+# component Mex Compiler
+if("MEX_COMPILER" IN_LIST Matlab_FIND_COMPONENTS)
+  find_program(
+    Matlab_MEX_COMPILER
+    "mex"
+    PATHS ${Matlab_BINARIES_DIR}
+    DOC "Matlab MEX compiler"
+    NO_DEFAULT_PATH
+  )
+  if(Matlab_MEX_COMPILER)
+    set(Matlab_MEX_COMPILER_FOUND TRUE)
+  endif()
+endif()
+
+# component MCC Compiler
+if("MCC_COMPILER" IN_LIST Matlab_FIND_COMPONENTS)
+  find_program(
+    Matlab_MCC_COMPILER
+    "mcc"
+    PATHS ${Matlab_BINARIES_DIR}
+    DOC "Matlab MCC compiler"
+    NO_DEFAULT_PATH
+  )
+  if(Matlab_MCC_COMPILER)
+    set(Matlab_MCC_COMPILER_FOUND TRUE)
+  endif()
+endif()
 
 set(Matlab_LIBRARIES
   ${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY}
diff --git a/Modules/FindPNG.cmake b/Modules/FindPNG.cmake
index a7908c5..bd400c7 100644
--- a/Modules/FindPNG.cmake
+++ b/Modules/FindPNG.cmake
@@ -69,8 +69,8 @@
     unset(_PNG_VERSION_SUFFIX_MIN)
   endif ()
   foreach(v IN LISTS _PNG_VERSION_SUFFIXES)
-    list(APPEND PNG_NAMES png${v} libpng${v})
-    list(APPEND PNG_NAMES_DEBUG png${v}d libpng${v}d)
+    list(APPEND PNG_NAMES png${v} libpng${v} libpng${v}_static)
+    list(APPEND PNG_NAMES_DEBUG png${v}d libpng${v}d libpng${v}_staticd)
   endforeach()
   unset(_PNG_VERSION_SUFFIXES)
   # For compatibility with versions prior to this multi-config search, honor
diff --git a/Modules/FindProtobuf.cmake b/Modules/FindProtobuf.cmake
index 670352c..2d45965 100644
--- a/Modules/FindProtobuf.cmake
+++ b/Modules/FindProtobuf.cmake
@@ -526,6 +526,11 @@
               INTERFACE_COMPILE_FEATURES cxx_std_11
             )
           endif()
+          if (MSVC AND NOT Protobuf_USE_STATIC_LIBS)
+            set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
+              INTERFACE_COMPILE_DEFINITIONS "PROTOBUF_USE_DLLS"
+            )
+          endif()
           if(UNIX AND TARGET Threads::Threads)
             set_property(TARGET protobuf::libprotobuf APPEND PROPERTY
                 INTERFACE_LINK_LIBRARIES Threads::Threads)
@@ -554,6 +559,11 @@
             set_target_properties(protobuf::libprotobuf-lite PROPERTIES
               IMPORTED_LOCATION_DEBUG "${Protobuf_LITE_LIBRARY_DEBUG}")
           endif()
+          if (MSVC AND NOT Protobuf_USE_STATIC_LIBS)
+            set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY
+              INTERFACE_COMPILE_DEFINITIONS "PROTOBUF_USE_DLLS"
+            )
+          endif()
           if(UNIX AND TARGET Threads::Threads)
             set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY
                 INTERFACE_LINK_LIBRARIES Threads::Threads)
@@ -587,6 +597,11 @@
               INTERFACE_COMPILE_FEATURES cxx_std_11
             )
           endif()
+          if (MSVC AND NOT Protobuf_USE_STATIC_LIBS)
+            set_property(TARGET protobuf::libprotoc APPEND PROPERTY
+              INTERFACE_COMPILE_DEFINITIONS "PROTOBUF_USE_DLLS"
+            )
+          endif()
           if(UNIX AND TARGET Threads::Threads)
             set_property(TARGET protobuf::libprotoc APPEND PROPERTY
                 INTERFACE_LINK_LIBRARIES Threads::Threads)
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index c0e843a..8faec03 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -54,7 +54,7 @@
 
 macro (_PYTHON_FIND_FRAMEWORKS)
   set (${_PYTHON_PREFIX}_FRAMEWORKS)
-  if (APPLE)
+  if (CMAKE_HOST_APPLE OR APPLE)
     set (_pff_frameworks ${CMAKE_FRAMEWORK_PATH}
                     $ENV{CMAKE_FRAMEWORK_PATH}
                     ~/Library/Frameworks
@@ -623,7 +623,7 @@
       endif()
 
       # Apple frameworks handling
-      if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
+      if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
         find_program (${_PYTHON_PREFIX}_EXECUTABLE
                       NAMES ${_${_PYTHON_PREFIX}_NAMES}
                       NAMES_PER_DIR
@@ -640,7 +640,7 @@
         endif()
       endif()
       # Windows registry
-      if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+      if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
         find_program (${_PYTHON_PREFIX}_EXECUTABLE
                       NAMES ${_${_PYTHON_PREFIX}_NAMES}
                             ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
@@ -681,7 +681,7 @@
       endif()
 
       # Apple frameworks handling
-      if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
+      if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
         find_program (${_PYTHON_PREFIX}_EXECUTABLE
                       NAMES ${_${_PYTHON_PREFIX}_NAMES}
                       NAMES_PER_DIR
@@ -694,7 +694,7 @@
         endif()
       endif()
       # Windows registry
-      if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+      if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
         find_program (${_PYTHON_PREFIX}_EXECUTABLE
                       NAMES ${_${_PYTHON_PREFIX}_NAMES}
                             ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
@@ -743,7 +743,7 @@
       endif()
 
       # Apple frameworks handling
-      if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
+      if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
         find_program (${_PYTHON_PREFIX}_EXECUTABLE
                       NAMES ${_${_PYTHON_PREFIX}_NAMES}
                       NAMES_PER_DIR
@@ -757,7 +757,7 @@
       endif()
 
       # Windows registry
-      if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
+      if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "FIRST")
         find_program (${_PYTHON_PREFIX}_EXECUTABLE
                       NAMES ${_${_PYTHON_PREFIX}_NAMES}
                             ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
@@ -793,7 +793,7 @@
       # For example, typical systems have 'python' for version 2.* and 'python3'
       # for version 3.*. So looking for names per dir will find, potentially,
       # systematically 'python' (i.e. version 2) even if version 3 is searched.
-      if (WIN32)
+      if (CMAKE_HOST_WIN32)
         find_program (${_PYTHON_PREFIX}_EXECUTABLE
                       NAMES ${_${_PYTHON_PREFIX}_NAMES}
                             python
@@ -808,7 +808,7 @@
       endif()
 
       # Apple frameworks handling
-      if (APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
+      if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "LAST")
         find_program (${_PYTHON_PREFIX}_EXECUTABLE
                       NAMES ${_${_PYTHON_PREFIX}_NAMES}
                       NAMES_PER_DIR
@@ -818,7 +818,7 @@
       endif()
 
       # Windows registry
-      if (WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
+      if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
         find_program (${_PYTHON_PREFIX}_EXECUTABLE
                       NAMES ${_${_PYTHON_PREFIX}_NAMES}
                             ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES}
@@ -1145,7 +1145,6 @@
     else()
       list (REMOVE_ITEM CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX})
     endif()
-  else()
   endif()
 
   # if python interpreter is found, use its location and version to ensure consistency
diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake
index ae8d72d..55da55f 100644
--- a/Modules/FindVulkan.cmake
+++ b/Modules/FindVulkan.cmake
@@ -5,7 +5,7 @@
 FindVulkan
 ----------
 
-Find Vulkan, which isis a low-overhead, cross-platform 3D graphics
+Find Vulkan, which is a low-overhead, cross-platform 3D graphics
 and computing API.
 
 IMPORTED Targets
diff --git a/Modules/InstallRequiredSystemLibraries.cmake b/Modules/InstallRequiredSystemLibraries.cmake
index 0a98895..e3eeea4 100644
--- a/Modules/InstallRequiredSystemLibraries.cmake
+++ b/Modules/InstallRequiredSystemLibraries.cmake
@@ -210,8 +210,8 @@
   set(_MSVC_IDE_VERSION "")
   if(MSVC_VERSION GREATER_EQUAL 2000)
     message(WARNING "MSVC ${MSVC_VERSION} not yet supported.")
-  elseif(MSVC_VERSION_VERSION GREATER_EQUAL 143)
-    message(WARNING "MSVC toolset v${MSVC_VERSION_VERSION} not yet supported.")
+  elseif(MSVC_TOOLSET_VERSION GREATER_EQUAL 143)
+    message(WARNING "MSVC toolset v${MSVC_TOOLSET_VERSION} not yet supported.")
   elseif(MSVC_TOOLSET_VERSION EQUAL 142)
     set(MSVC_REDIST_NAME VC142)
     set(_MSVC_DLL_VERSION 140)
@@ -251,10 +251,18 @@
     endif()
     if(NOT vs VERSION_LESS 15)
       set(_vs_redist_paths "")
-      cmake_host_system_information(RESULT _vs_dir QUERY VS_${vs}_DIR) # undocumented query
-      if(IS_DIRECTORY "${_vs_dir}")
-        file(GLOB _vs_redist_paths "${_vs_dir}/VC/Redist/MSVC/*")
-      endif()
+      # The toolset and its redistributables may come with any VS version 15 or newer.
+      set(_MSVC_IDE_VERSIONS 16 15)
+      foreach(_vs_ver ${_MSVC_IDE_VERSIONS})
+        set(_vs_glob_redist_paths "")
+        cmake_host_system_information(RESULT _vs_dir QUERY VS_${_vs_ver}_DIR) # undocumented query
+        if(IS_DIRECTORY "${_vs_dir}")
+          file(GLOB _vs_glob_redist_paths "${_vs_dir}/VC/Redist/MSVC/*")
+          list(APPEND _vs_redist_paths ${_vs_glob_redist_paths})
+        endif()
+        unset(_vs_glob_redist_paths)
+      endforeach()
+      unset(_MSVC_IDE_VERSIONS)
       unset(_vs_dir)
     else()
       get_filename_component(_vs_dir
diff --git a/Modules/Platform/AIX-GNU.cmake b/Modules/Platform/AIX-GNU.cmake
index 0abbb61..61d213a 100644
--- a/Modules/Platform/AIX-GNU.cmake
+++ b/Modules/Platform/AIX-GNU.cmake
@@ -8,23 +8,26 @@
 endif()
 set(__AIX_COMPILER_GNU 1)
 
-#
-# By default, runtime linking is enabled. All shared objects specified on the command line
-# will be listed, even if there are no symbols referenced, in the output file.
-string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " -Wl,-brtl")
-string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " -Wl,-brtl")
-string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " -Wl,-brtl")
-
-
 macro(__aix_compiler_gnu lang)
   set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-blibpath:")
   set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
-  string(APPEND CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS " -Wl,-G,-bnoipath")
-  set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-bexpall")
+  string(APPEND CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS " -Wl,-bnoipath")
+  set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-bexpall") # CMP0065 old behavior
   set(CMAKE_${lang}_USE_IMPLICIT_LINK_DIRECTORIES_IN_RUNTIME_PATH 1)
 
   set(CMAKE_${lang}_LINK_FLAGS "-Wl,-bnoipath")
   if(CMAKE_${lang}_COMPILER_VERSION VERSION_LESS 7 OR CMAKE_SYSTEM_VERSION VERSION_LESS 7.1)
     unset(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY)
   endif()
+
+  # Construct the export list ourselves to pass only the object files so
+  # that we export only the symbols actually provided by the sources.
+  set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
+    "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/objects.exp <OBJECTS>"
+    "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
+    )
+
+  set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS
+    "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -l . <OBJECTS>"
+    "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<TARGET_IMPLIB> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
 endmacro()
diff --git a/Modules/Platform/AIX-XL.cmake b/Modules/Platform/AIX-XL.cmake
index 06a806b..64b0bc1 100644
--- a/Modules/Platform/AIX-XL.cmake
+++ b/Modules/Platform/AIX-XL.cmake
@@ -8,43 +8,24 @@
 endif()
 set(__AIX_COMPILER_XL 1)
 
-#
-# By default, runtime linking is enabled. All shared objects specified on the command line
-# will be listed, even if there are no symbols referenced, in the output file.
-string(APPEND CMAKE_SHARED_LINKER_FLAGS_INIT " -Wl,-brtl")
-string(APPEND CMAKE_MODULE_LINKER_FLAGS_INIT " -Wl,-brtl")
-string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " -Wl,-brtl")
-
-
 macro(__aix_compiler_xl lang)
   set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-blibpath:")
   set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
-  set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-G -Wl,-bnoipath")  # -shared
-  set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-bexpall")
+  string(APPEND CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS " -Wl,-bnoipath")
+  set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "-Wl,-bexpall") # CMP0065 old behavior
   set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS " ")
   set(CMAKE_SHARED_MODULE_${lang}_FLAGS  " ")
 
   set(CMAKE_${lang}_LINK_FLAGS "-Wl,-bnoipath")
 
-  # Find the CreateExportList program that comes with this toolchain.
-  find_program(CMAKE_XL_CreateExportList
-    NAMES CreateExportList
-    DOC "IBM XL CreateExportList tool"
+  # Construct the export list ourselves to pass only the object files so
+  # that we export only the symbols actually provided by the sources.
+  set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
+    "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/objects.exp <OBJECTS>"
+    "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
     )
 
-  # CMAKE_XL_CreateExportList is part of the AIX XL compilers but not the linux ones.
-  # If we found the tool, we'll use it to create exports, otherwise stick with the regular
-  # create shared library compile line.
-  if (CMAKE_XL_CreateExportList)
-    # The compiler front-end passes all object files, archive files, and shared
-    # library files named on the command line to CreateExportList to create a
-    # list of all symbols to be exported from the shared library.  This causes
-    # all archive members to be copied into the shared library whether they are
-    # needed or not.  Instead we run the tool ourselves to pass only the object
-    # files so that we export only the symbols actually provided by the sources.
-    set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
-      "${CMAKE_XL_CreateExportList} <OBJECT_DIR>/objects.exp <OBJECTS>"
-      "<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/objects.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
-      )
-  endif()
+  set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS
+    "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -l . <OBJECTS>"
+    "<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<TARGET_IMPLIB> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
 endmacro()
diff --git a/Modules/Platform/AIX.cmake b/Modules/Platform/AIX.cmake
index 551a995..03cef51 100644
--- a/Modules/Platform/AIX.cmake
+++ b/Modules/Platform/AIX.cmake
@@ -1,5 +1,7 @@
 set(CMAKE_SHARED_LIBRARY_PREFIX "lib")          # lib
 set(CMAKE_SHARED_LIBRARY_SUFFIX ".so")          # .so
+set(CMAKE_AIX_IMPORT_FILE_PREFIX "")
+set(CMAKE_AIX_IMPORT_FILE_SUFFIX ".imp")
 set(CMAKE_DL_LIBS "-lld")
 
 # RPATH support on AIX is called libpath.  By default the runtime
diff --git a/Modules/Platform/AIX/ExportImportList b/Modules/Platform/AIX/ExportImportList
new file mode 100755
index 0000000..4f67ef5
--- /dev/null
+++ b/Modules/Platform/AIX/ExportImportList
@@ -0,0 +1,53 @@
+#!/bin/sh
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+# This script is internal to CMake and meant only to be
+# invoked by CMake-generated build systems on AIX.
+
+usage='usage: ExportImportList -o <out-file> [-l <lib>] [--] <objects>...'
+
+die() {
+    echo "$@" 1>&2; exit 1
+}
+
+# Process command-line arguments.
+out=''
+lib=''
+while test "$#" != 0; do
+    case "$1" in
+    -l) shift; lib="$1" ;;
+    -o) shift; out="$1" ;;
+    --) shift; break ;;
+    -*) die "$usage" ;;
+    *)  break ;;
+    esac
+    shift
+done
+test -n "$out" || die "$usage"
+
+# Collect symbols exported from all object files.
+out_tmp="$out.tmp$$"
+trap 'rm -f "$out_tmp"' EXIT INT TERM
+for f in "$@"; do
+    dump -tov -X 32_64 "$f" |
+    awk '
+        BEGIN {
+            V["EXPORTED"]=" export"
+            V["PROTECTED"]=" protected"
+        }
+        /^\[[0-9]+\]\tm +[^ ]+ +\.(text|data|bss) +[^ ]+ +(extern|weak) +(EXPORTED|PROTECTED| ) / {
+            if (!match($NF,/^(\.|__sinit|__sterm|__[0-9]+__)/)) {
+                print $NF V[$(NF-1)]
+            }
+        }
+    '
+done > "$out_tmp"
+
+# Generate the export/import file.
+{
+    if test -n "$lib"; then
+        echo "#! $lib"
+    fi
+    sort -u "$out_tmp"
+} > "$out"
diff --git a/Modules/Platform/Android-Clang.cmake b/Modules/Platform/Android-Clang.cmake
index 9ed1e01..847178f 100644
--- a/Modules/Platform/Android-Clang.cmake
+++ b/Modules/Platform/Android-Clang.cmake
@@ -40,6 +40,9 @@
   endif()
   if(NOT CMAKE_${lang}_COMPILER_TARGET)
     set(CMAKE_${lang}_COMPILER_TARGET "${_ANDROID_ABI_CLANG_TARGET}")
+    if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
+      string(APPEND CMAKE_${lang}_COMPILER_TARGET "${CMAKE_SYSTEM_VERSION}")
+    endif()
     list(APPEND CMAKE_${lang}_COMPILER_PREDEFINES_COMMAND "--target=${CMAKE_${lang}_COMPILER_TARGET}")
   endif()
 endmacro()
diff --git a/Modules/Platform/Android-Common.cmake b/Modules/Platform/Android-Common.cmake
index f8b9346..1affcd0 100644
--- a/Modules/Platform/Android-Common.cmake
+++ b/Modules/Platform/Android-Common.cmake
@@ -47,7 +47,41 @@
 endif()
 
 if(CMAKE_ANDROID_STL_TYPE)
-  if(CMAKE_ANDROID_NDK)
+  if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
+    if(CMAKE_ANDROID_STL_TYPE STREQUAL "system")
+      set(_ANDROID_STL_EXCEPTIONS 0)
+      set(_ANDROID_STL_RTTI 0)
+      macro(__android_stl lang)
+        string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libstdc++")
+      endmacro()
+    elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "c++_static")
+      set(_ANDROID_STL_EXCEPTIONS 1)
+      set(_ANDROID_STL_RTTI 1)
+      macro(__android_stl lang)
+        string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libc++")
+        string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -static-libstdc++")
+      endmacro()
+    elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "c++_shared")
+      set(_ANDROID_STL_EXCEPTIONS 1)
+      set(_ANDROID_STL_RTTI 1)
+      macro(__android_stl lang)
+        string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libc++")
+      endmacro()
+    elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "none")
+      set(_ANDROID_STL_RTTI 0)
+      set(_ANDROID_STL_EXCEPTIONS 0)
+      macro(__android_stl lang)
+        # FIXME: Add a way to add project-wide language-specific compile-only flags.
+        set(CMAKE_CXX_COMPILE_OBJECT
+          "<CMAKE_CXX_COMPILER>  <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE> -nostdinc++")
+        string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -nostdlib++")
+      endmacro()
+    else()
+      message(FATAL_ERROR
+        "Android: STL '${CMAKE_ANDROID_STL_TYPE}' not supported by this NDK."
+        )
+    endif()
+  elseif(CMAKE_ANDROID_NDK)
 
     macro(__android_stl_inc lang dir req)
       if(EXISTS "${dir}")
@@ -152,6 +186,10 @@
     __android_stl(CXX)
   endif()
 
+  if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
+    string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -latomic -lm")
+  endif()
+
   # <ndk>/build/core/definitions.mk appends the sysroot's include directory
   # explicitly at the end of the command-line include path so that it
   # precedes the toolchain's builtin include directories.  This is
@@ -161,7 +199,7 @@
   #
   # Do not do this for a standalone toolchain because it is already
   # tied to a specific API version.
-  if(CMAKE_ANDROID_NDK)
+  if(CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
     if(CMAKE_SYSROOT_COMPILE)
       set(_cmake_sysroot_compile "${CMAKE_SYSROOT_COMPILE}")
     else()
@@ -170,7 +208,7 @@
     if(NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
       list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES
         "${_cmake_sysroot_compile}/usr/include"
-        "${_cmake_sysroot_compile}/usr/include/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}"
+        "${_cmake_sysroot_compile}/usr/include/${CMAKE_ANDROID_ARCH_TRIPLE}"
         )
     else()
       list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${_cmake_sysroot_compile}/usr/include")
diff --git a/Modules/Platform/Android-Determine.cmake b/Modules/Platform/Android-Determine.cmake
index bb42eed..e7c1b48 100644
--- a/Modules/Platform/Android-Determine.cmake
+++ b/Modules/Platform/Android-Determine.cmake
@@ -198,32 +198,66 @@
   message(FATAL_ERROR "Android: The API specified by CMAKE_SYSTEM_VERSION='${CMAKE_SYSTEM_VERSION}' is not an integer.")
 endif()
 
+if(CMAKE_ANDROID_NDK)
+  # Identify the host platform.
+  if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
+    if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
+      set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "darwin-x86_64")
+    else()
+      set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "darwin-x86")
+    endif()
+  elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
+    if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
+      set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "linux-x86_64")
+    else()
+      set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "linux-x86")
+    endif()
+  elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
+    if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64")
+      set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "windows-x86_64")
+    else()
+      set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "windows")
+    endif()
+  else()
+    message(FATAL_ERROR "Android: Builds hosted on '${CMAKE_HOST_SYSTEM_NAME}' not supported.")
+  endif()
+
+  # Look for a unified toolchain/sysroot provided with the NDK.
+  set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED "${CMAKE_ANDROID_NDK}/toolchains/llvm/prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}")
+  if(NOT IS_DIRECTORY "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/sysroot")
+    set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED "")
+  endif()
+else()
+  set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG "")
+  set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED "")
+endif()
+
 # https://developer.android.com/ndk/guides/abis.html
 
 set(_ANDROID_ABI_arm64-v8a_PROC     "aarch64")
 set(_ANDROID_ABI_arm64-v8a_ARCH     "arm64")
-set(_ANDROID_ABI_arm64-v8a_HEADER   "aarch64-linux-android")
+set(_ANDROID_ABI_arm64-v8a_TRIPLE   "aarch64-linux-android")
 set(_ANDROID_ABI_armeabi-v7a_PROC   "armv7-a")
 set(_ANDROID_ABI_armeabi-v7a_ARCH   "arm")
-set(_ANDROID_ABI_armeabi-v7a_HEADER "arm-linux-androideabi")
+set(_ANDROID_ABI_armeabi-v7a_TRIPLE "arm-linux-androideabi")
 set(_ANDROID_ABI_armeabi-v6_PROC    "armv6")
 set(_ANDROID_ABI_armeabi-v6_ARCH    "arm")
-set(_ANDROID_ABI_armeabi-v6_HEADER  "arm-linux-androideabi")
+set(_ANDROID_ABI_armeabi-v6_TRIPLE  "arm-linux-androideabi")
 set(_ANDROID_ABI_armeabi_PROC       "armv5te")
 set(_ANDROID_ABI_armeabi_ARCH       "arm")
-set(_ANDROID_ABI_armeabi_HEADER     "arm-linux-androideabi")
+set(_ANDROID_ABI_armeabi_TRIPLE     "arm-linux-androideabi")
 set(_ANDROID_ABI_mips_PROC          "mips")
 set(_ANDROID_ABI_mips_ARCH          "mips")
-set(_ANDROID_ABI_mips_HEADER        "mipsel-linux-android")
+set(_ANDROID_ABI_mips_TRIPLE        "mipsel-linux-android")
 set(_ANDROID_ABI_mips64_PROC        "mips64")
 set(_ANDROID_ABI_mips64_ARCH        "mips64")
-set(_ANDROID_ABI_mips64_HEADER      "mips64el-linux-android")
+set(_ANDROID_ABI_mips64_TRIPLE      "mips64el-linux-android")
 set(_ANDROID_ABI_x86_PROC           "i686")
 set(_ANDROID_ABI_x86_ARCH           "x86")
-set(_ANDROID_ABI_x86_HEADER         "i686-linux-android")
+set(_ANDROID_ABI_x86_TRIPLE         "i686-linux-android")
 set(_ANDROID_ABI_x86_64_PROC        "x86_64")
 set(_ANDROID_ABI_x86_64_ARCH        "x86_64")
-set(_ANDROID_ABI_x86_64_HEADER      "x86_64-linux-android")
+set(_ANDROID_ABI_x86_64_TRIPLE      "x86_64-linux-android")
 
 set(_ANDROID_PROC_aarch64_ARCH_ABI "arm64-v8a")
 set(_ANDROID_PROC_armv7-a_ARCH_ABI "armeabi-v7a")
@@ -308,7 +342,7 @@
     "does not match architecture '${CMAKE_ANDROID_ARCH}' for the ABI '${CMAKE_ANDROID_ARCH_ABI}'."
     )
 endif()
-set(CMAKE_ANDROID_ARCH_HEADER_TRIPLE "${_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_HEADER}")
+set(CMAKE_ANDROID_ARCH_TRIPLE "${_ANDROID_ABI_${CMAKE_ANDROID_ARCH_ABI}_TRIPLE}")
 
 # Select a processor.
 if(NOT CMAKE_SYSTEM_PROCESSOR)
@@ -321,7 +355,7 @@
 endif()
 
 if(CMAKE_ANDROID_NDK AND NOT DEFINED CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
-  if(IS_DIRECTORY "${CMAKE_ANDROID_NDK}/sysroot/usr/include/${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}")
+  if(IS_DIRECTORY "${CMAKE_ANDROID_NDK}/sysroot/usr/include/${CMAKE_ANDROID_ARCH_TRIPLE}")
     # Unified headers exist so we use them by default.
     set(CMAKE_ANDROID_NDK_DEPRECATED_HEADERS 0)
   else()
@@ -340,8 +374,10 @@
 
 if(CMAKE_ANDROID_NDK)
   string(APPEND CMAKE_SYSTEM_CUSTOM_CODE
-    "set(CMAKE_ANDROID_ARCH_HEADER_TRIPLE \"${CMAKE_ANDROID_ARCH_HEADER_TRIPLE}\")\n"
+    "set(CMAKE_ANDROID_ARCH_TRIPLE \"${CMAKE_ANDROID_ARCH_TRIPLE}\")\n"
     "set(CMAKE_ANDROID_NDK_DEPRECATED_HEADERS \"${CMAKE_ANDROID_NDK_DEPRECATED_HEADERS}\")\n"
+    "set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG \"${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}\")\n"
+    "set(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED \"${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}\")\n"
     )
 endif()
 
diff --git a/Modules/Platform/Android-Initialize.cmake b/Modules/Platform/Android-Initialize.cmake
index a434f90..a5d2820 100644
--- a/Modules/Platform/Android-Initialize.cmake
+++ b/Modules/Platform/Android-Initialize.cmake
@@ -17,6 +17,13 @@
   return()
 endif()
 
+set(CMAKE_BUILD_TYPE_INIT Debug)
+
+# Skip sysroot selection if the NDK has a unified toolchain.
+if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
+  return()
+endif()
+
 if(NOT CMAKE_SYSROOT)
   if(CMAKE_ANDROID_NDK)
     set(CMAKE_SYSROOT "${CMAKE_ANDROID_NDK}/platforms/android-${CMAKE_SYSTEM_VERSION}/arch-${CMAKE_ANDROID_ARCH}")
@@ -40,5 +47,3 @@
     "Android: No CMAKE_SYSROOT was selected."
     )
 endif()
-
-set(CMAKE_BUILD_TYPE_INIT Debug)
diff --git a/Modules/Platform/Android/Determine-Compiler-NDK.cmake b/Modules/Platform/Android/Determine-Compiler-NDK.cmake
index 5f2cc52..e009c10 100644
--- a/Modules/Platform/Android/Determine-Compiler-NDK.cmake
+++ b/Modules/Platform/Android/Determine-Compiler-NDK.cmake
@@ -1,6 +1,31 @@
 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
 # file Copyright.txt or https://cmake.org/licensing for details.
 
+# In Android NDK r19 and above there is a single clang toolchain.
+if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
+  if(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION AND NOT CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION STREQUAL "clang")
+    message(FATAL_ERROR
+      "Android: The CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION value '${CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION}' "
+      "is not supported by this NDK.  It must be 'clang' or not set at all."
+      )
+  endif()
+  message(STATUS "Android: Selected unified Clang toolchain")
+  set(_ANDROID_TOOL_NDK_TOOLCHAIN_VERSION "clang")
+  set(_ANDROID_TOOL_C_COMPILER "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin/clang${_ANDROID_HOST_EXT}")
+  set(_ANDROID_TOOL_C_TOOLCHAIN_MACHINE "${CMAKE_ANDROID_ARCH_TRIPLE}")
+  set(_ANDROID_TOOL_C_TOOLCHAIN_VERSION "")
+  set(_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN "")
+  set(_ANDROID_TOOL_C_TOOLCHAIN_PREFIX "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin/${CMAKE_ANDROID_ARCH_TRIPLE}-")
+  set(_ANDROID_TOOL_C_TOOLCHAIN_SUFFIX "${_ANDROID_HOST_EXT}")
+  set(_ANDROID_TOOL_CXX_COMPILER "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin/clang++${_ANDROID_HOST_EXT}")
+  set(_ANDROID_TOOL_CXX_TOOLCHAIN_MACHINE "${CMAKE_ANDROID_ARCH_TRIPLE}")
+  set(_ANDROID_TOOL_CXX_TOOLCHAIN_VERSION "")
+  set(_ANDROID_TOOL_CXX_COMPILER_EXTERNAL_TOOLCHAIN "")
+  set(_ANDROID_TOOL_CXX_TOOLCHAIN_PREFIX "${CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED}/bin/${CMAKE_ANDROID_ARCH_TRIPLE}-")
+  set(_ANDROID_TOOL_CXX_TOOLCHAIN_SUFFIX "${_ANDROID_HOST_EXT}")
+  return()
+endif()
+
 # In Android NDK releases there is build system toolchain selection logic in
 # these files:
 #
@@ -195,40 +220,16 @@
   set(_ANDROID_TOOL_PREFIX "${CMAKE_MATCH_1}")
 endif()
 
-# Identify the host platform.
-if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
-  if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
-    set(_ANDROID_HOST_DIR "darwin-x86_64")
-  else()
-    set(_ANDROID_HOST_DIR "darwin-x86")
-  endif()
-elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
-  if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "x86_64")
-    set(_ANDROID_HOST_DIR "linux-x86_64")
-  else()
-    set(_ANDROID_HOST_DIR "linux-x86")
-  endif()
-elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
-  if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "AMD64")
-    set(_ANDROID_HOST_DIR "windows-x86_64")
-  else()
-    set(_ANDROID_HOST_DIR "windows")
-  endif()
-else()
-  message(FATAL_ERROR "Android: Builds hosted on '${CMAKE_HOST_SYSTEM_NAME}' not supported.")
-endif()
-
 # Help CMakeFindBinUtils locate things.
 set(_CMAKE_TOOLCHAIN_PREFIX "${_ANDROID_TOOL_PREFIX}")
 
-set(_ANDROID_TOOL_NDK_TOOLCHAIN_HOST_TAG "${_ANDROID_HOST_DIR}")
 set(_ANDROID_TOOL_NDK_TOOLCHAIN_VERSION "${_ANDROID_TOOL_VERS_NDK}")
 
 # _ANDROID_TOOL_PREFIX should now match `gcc -dumpmachine`.
 string(REGEX REPLACE "-$" "" _ANDROID_TOOL_C_TOOLCHAIN_MACHINE "${_ANDROID_TOOL_PREFIX}")
 
 set(_ANDROID_TOOL_C_TOOLCHAIN_VERSION "${_ANDROID_TOOL_VERS}")
-set(_ANDROID_TOOL_C_TOOLCHAIN_PREFIX "${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_NAME}/prebuilt/${_ANDROID_HOST_DIR}/bin/${_ANDROID_TOOL_PREFIX}")
+set(_ANDROID_TOOL_C_TOOLCHAIN_PREFIX "${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_NAME}/prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}/bin/${_ANDROID_TOOL_PREFIX}")
 set(_ANDROID_TOOL_C_TOOLCHAIN_SUFFIX "${_ANDROID_HOST_EXT}")
 
 set(_ANDROID_TOOL_CXX_TOOLCHAIN_MACHINE "${_ANDROID_TOOL_C_TOOLCHAIN_MACHINE}")
@@ -238,9 +239,9 @@
 
 if(_ANDROID_TOOL_CLANG_NAME)
   message(STATUS "Android: Selected Clang toolchain '${_ANDROID_TOOL_CLANG_NAME}' with GCC toolchain '${_ANDROID_TOOL_NAME}'")
-  set(_ANDROID_TOOL_C_COMPILER "${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_LLVM_NAME}/prebuilt/${_ANDROID_HOST_DIR}/bin/clang${_ANDROID_HOST_EXT}")
-  set(_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN ${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_NAME}/prebuilt/${_ANDROID_HOST_DIR})
-  set(_ANDROID_TOOL_CXX_COMPILER "${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_LLVM_NAME}/prebuilt/${_ANDROID_HOST_DIR}/bin/clang++${_ANDROID_HOST_EXT}")
+  set(_ANDROID_TOOL_C_COMPILER "${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_LLVM_NAME}/prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}/bin/clang${_ANDROID_HOST_EXT}")
+  set(_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN ${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_NAME}/prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG})
+  set(_ANDROID_TOOL_CXX_COMPILER "${CMAKE_ANDROID_NDK}/toolchains/${_ANDROID_TOOL_LLVM_NAME}/prebuilt/${CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG}/bin/clang++${_ANDROID_HOST_EXT}")
   set(_ANDROID_TOOL_CXX_COMPILER_EXTERNAL_TOOLCHAIN "${_ANDROID_TOOL_C_COMPILER_EXTERNAL_TOOLCHAIN}")
 else()
   message(STATUS "Android: Selected GCC toolchain '${_ANDROID_TOOL_NAME}'")
@@ -267,4 +268,3 @@
 unset(_ANDROID_TOOL_CLANG_NAME)
 unset(_ANDROID_TOOL_CLANG_VERS)
 unset(_ANDROID_TOOL_LLVM_NAME)
-unset(_ANDROID_HOST_DIR)
diff --git a/Modules/Platform/Android/Determine-Compiler-Standalone.cmake b/Modules/Platform/Android/Determine-Compiler-Standalone.cmake
index 4c1ac1f..5095aff 100644
--- a/Modules/Platform/Android/Determine-Compiler-Standalone.cmake
+++ b/Modules/Platform/Android/Determine-Compiler-Standalone.cmake
@@ -62,5 +62,4 @@
   set(_ANDROID_TOOL_CXX_COMPILER_EXTERNAL_TOOLCHAIN "")
 endif()
 
-set(_ANDROID_TOOL_NDK_TOOLCHAIN_HOST_TAG "")
 set(_ANDROID_TOOL_NDK_TOOLCHAIN_VERSION "")
diff --git a/Modules/Platform/Android/Determine-Compiler.cmake b/Modules/Platform/Android/Determine-Compiler.cmake
index a03ebcc..5c6b97b 100644
--- a/Modules/Platform/Android/Determine-Compiler.cmake
+++ b/Modules/Platform/Android/Determine-Compiler.cmake
@@ -40,7 +40,6 @@
 elseif(CMAKE_ANDROID_STANDALONE_TOOLCHAIN)
   include(Platform/Android/Determine-Compiler-Standalone)
 else()
-  set(_ANDROID_TOOL_NDK_TOOLCHAIN_HOST_TAG "")
   set(_ANDROID_TOOL_NDK_TOOLCHAIN_VERSION "")
   set(_ANDROID_TOOL_C_COMPILER "")
   set(_ANDROID_TOOL_C_TOOLCHAIN_MACHINE "")
@@ -65,7 +64,6 @@
 
     # Save the Android-specific information in CMake${lang}Compiler.cmake.
     set(CMAKE_${lang}_COMPILER_CUSTOM_CODE "
-set(CMAKE_ANDROID_NDK_TOOLCHAIN_HOST_TAG \"${_ANDROID_TOOL_NDK_TOOLCHAIN_HOST_TAG}\")
 set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION \"${_ANDROID_TOOL_NDK_TOOLCHAIN_VERSION}\")
 set(CMAKE_${lang}_ANDROID_TOOLCHAIN_MACHINE \"${_ANDROID_TOOL_${lang}_TOOLCHAIN_MACHINE}\")
 set(CMAKE_${lang}_ANDROID_TOOLCHAIN_VERSION \"${_ANDROID_TOOL_${lang}_TOOLCHAIN_VERSION}\")
diff --git a/Modules/Platform/Android/abi-common.cmake b/Modules/Platform/Android/abi-common.cmake
index 6bce3c7..b01ef61 100644
--- a/Modules/Platform/Android/abi-common.cmake
+++ b/Modules/Platform/Android/abi-common.cmake
@@ -3,7 +3,7 @@
   " -no-canonical-prefixes"
   )
 
-if(CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
+if(CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED AND NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
   string(APPEND _ANDROID_ABI_INIT_CFLAGS " -D__ANDROID_API__=${CMAKE_SYSTEM_VERSION}")
 endif()
 
diff --git a/Modules/Platform/Apple-XL-C.cmake b/Modules/Platform/Apple-XL-C.cmake
index 2aeb132..e4fc3dd 100644
--- a/Modules/Platform/Apple-XL-C.cmake
+++ b/Modules/Platform/Apple-XL-C.cmake
@@ -1,4 +1,3 @@
-set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-qmkshrobj")
 set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle")
 
 # Enable shared library versioning.
diff --git a/Modules/Platform/Apple-XL-CXX.cmake b/Modules/Platform/Apple-XL-CXX.cmake
index f8e1906..ea330c8 100644
--- a/Modules/Platform/Apple-XL-CXX.cmake
+++ b/Modules/Platform/Apple-XL-CXX.cmake
@@ -1,4 +1,3 @@
-set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-qmkshrobj")
 set(CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS "-bundle")
 
 # Enable shared library versioning.
diff --git a/Modules/Platform/Linux-XL-C.cmake b/Modules/Platform/Linux-XL-C.cmake
index d595e44..ef0c52b 100644
--- a/Modules/Platform/Linux-XL-C.cmake
+++ b/Modules/Platform/Linux-XL-C.cmake
@@ -1,2 +1 @@
-set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-qmkshrobj")
 set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-Wl,-export-dynamic")
diff --git a/Modules/Platform/Linux-XL-CXX.cmake b/Modules/Platform/Linux-XL-CXX.cmake
index 5ceb255..aa57d6e 100644
--- a/Modules/Platform/Linux-XL-CXX.cmake
+++ b/Modules/Platform/Linux-XL-CXX.cmake
@@ -1,2 +1 @@
-set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-qmkshrobj")
 set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "-Wl,-export-dynamic")
diff --git a/Modules/Platform/Linux-XL-Fortran.cmake b/Modules/Platform/Linux-XL-Fortran.cmake
index a878991..d9b4c2d 100644
--- a/Modules/Platform/Linux-XL-Fortran.cmake
+++ b/Modules/Platform/Linux-XL-Fortran.cmake
@@ -1,2 +1 @@
-set(CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS "-qmkshrobj")
 set(CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS "-Wl,-export-dynamic")
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 0316532..8117916 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -662,8 +662,6 @@
   cmTryCompileCommand.h
   cmTryRunCommand.cxx
   cmTryRunCommand.h
-  cmUnexpectedCommand.cxx
-  cmUnexpectedCommand.h
   cmUnsetCommand.cxx
   cmUnsetCommand.h
   cmUseMangledMesaCommand.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 7143749..bbf8be0 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
 # CMake version number components.
 set(CMake_VERSION_MAJOR 3)
 set(CMake_VERSION_MINOR 15)
-set(CMake_VERSION_PATCH 20190712)
-#set(CMake_VERSION_RC 1)
+set(CMake_VERSION_PATCH 20190729)
+#set(CMake_VERSION_RC 0)
diff --git a/Source/CMakeVersionCompute.cmake b/Source/CMakeVersionCompute.cmake
index 72a5800..160f470 100644
--- a/Source/CMakeVersionCompute.cmake
+++ b/Source/CMakeVersionCompute.cmake
@@ -16,7 +16,7 @@
 set(CMake_VERSION ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH})
 if(CMake_VERSION_SOURCE)
   set(CMake_VERSION_SUFFIX "${CMake_VERSION_SOURCE}")
-elseif(CMake_VERSION_RC)
+elseif(DEFINED CMake_VERSION_RC)
   set(CMake_VERSION_SUFFIX "rc${CMake_VERSION_RC}")
 else()
   set(CMake_VERSION_SUFFIX "")
diff --git a/Source/CPack/cmCPackExternalGenerator.cxx b/Source/CPack/cmCPackExternalGenerator.cxx
index 9dc9853..b4c7a5a 100644
--- a/Source/CPack/cmCPackExternalGenerator.cxx
+++ b/Source/CPack/cmCPackExternalGenerator.cxx
@@ -2,7 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmCPackExternalGenerator.h"
 
-#include "cmAlgorithms.h"
 #include "cmCPackComponentGroup.h"
 #include "cmCPackLog.h"
 #include "cmMakefile.h"
@@ -17,6 +16,8 @@
 #include <utility>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 int cmCPackExternalGenerator::InitializeInternal()
 {
   this->SetOption("CPACK_EXTERNAL_KNOWN_VERSIONS", "1.0");
diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx
index 4a91698..512ac7a 100644
--- a/Source/CPack/cmCPackGenerator.cxx
+++ b/Source/CPack/cmCPackGenerator.cxx
@@ -235,7 +235,7 @@
     return 0;
   }
 
-  // If the CPackConfig file sets CPACK_INSTALL_SCRIPT then run them
+  // If the CPackConfig file sets CPACK_INSTALL_SCRIPT(S) then run them
   // as listed
   if (!this->InstallProjectViaInstallScript(setDestDir,
                                             tempInstallDirectory)) {
@@ -448,7 +448,19 @@
 int cmCPackGenerator::InstallProjectViaInstallScript(
   bool setDestDir, const std::string& tempInstallDirectory)
 {
-  const char* cmakeScripts = this->GetOption("CPACK_INSTALL_SCRIPT");
+  const char* cmakeScripts = this->GetOption("CPACK_INSTALL_SCRIPTS");
+  {
+    const char* const cmakeScript = this->GetOption("CPACK_INSTALL_SCRIPT");
+    if (cmakeScript && cmakeScripts) {
+      cmCPackLogger(
+        cmCPackLog::LOG_WARNING,
+        "Both CPACK_INSTALL_SCRIPTS and CPACK_INSTALL_SCRIPT are set, "
+        "the latter will be ignored."
+          << std::endl);
+    } else if (cmakeScript && !cmakeScripts) {
+      cmakeScripts = cmakeScript;
+    }
+  }
   if (cmakeScripts && *cmakeScripts) {
     cmCPackLogger(cmCPackLog::LOG_OUTPUT,
                   "- Install scripts: " << cmakeScripts << std::endl);
@@ -747,7 +759,7 @@
     if (this->GetOption("CPACK_INSTALL_PREFIX")) {
       dir += this->GetOption("CPACK_INSTALL_PREFIX");
     }
-    mf.AddDefinition("CMAKE_INSTALL_PREFIX", dir.c_str());
+    mf.AddDefinition("CMAKE_INSTALL_PREFIX", dir);
 
     cmCPackLogger(
       cmCPackLog::LOG_DEBUG,
@@ -787,7 +799,7 @@
       return 0;
     }
   } else {
-    mf.AddDefinition("CMAKE_INSTALL_PREFIX", tempInstallDirectory.c_str());
+    mf.AddDefinition("CMAKE_INSTALL_PREFIX", tempInstallDirectory);
 
     if (!cmsys::SystemTools::MakeDirectory(tempInstallDirectory,
                                            default_dir_mode)) {
@@ -806,11 +818,11 @@
   }
 
   if (!buildConfig.empty()) {
-    mf.AddDefinition("BUILD_TYPE", buildConfig.c_str());
+    mf.AddDefinition("BUILD_TYPE", buildConfig);
   }
   std::string installComponentLowerCase = cmSystemTools::LowerCase(component);
   if (installComponentLowerCase != "all") {
-    mf.AddDefinition("CMAKE_INSTALL_COMPONENT", component.c_str());
+    mf.AddDefinition("CMAKE_INSTALL_COMPONENT", component);
   }
 
   // strip on TRUE, ON, 1, one or several file names, but not on
@@ -851,9 +863,8 @@
   // forward definition of CMAKE_ABSOLUTE_DESTINATION_FILES
   // to CPack (may be used by generators like CPack RPM or DEB)
   // in order to transparently handle ABSOLUTE PATH
-  if (mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) {
-    mf.AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES",
-                     mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES"));
+  if (const char* def = mf.GetDefinition("CMAKE_ABSOLUTE_DESTINATION_FILES")) {
+    mf.AddDefinition("CPACK_ABSOLUTE_DESTINATION_FILES", def);
   }
 
   // Now rebuild the list of files after installation
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 67b7ea6..89c3b1c 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -28,19 +28,20 @@
 #include "cmSystemTools.h"
 #include "cmake.h"
 
-static const char* cmDocumentationName[][2] = {
+namespace {
+const char* cmDocumentationName[][2] = {
   { nullptr, "  cpack - Packaging driver provided by CMake." },
   { nullptr, nullptr }
 };
 
-static const char* cmDocumentationUsage[][2] = {
+const char* cmDocumentationUsage[][2] = {
   // clang-format off
   { nullptr, "  cpack [options]" },
   { nullptr, nullptr }
   // clang-format on
 };
 
-static const char* cmDocumentationOptions[][2] = {
+const char* cmDocumentationOptions[][2] = {
   { "-G <generators>", "Override/define CPACK_GENERATOR" },
   { "-C <Configuration>", "Specify the project configuration" },
   { "-D <var>=<value>", "Set a CPack variable." },
@@ -89,10 +90,11 @@
   return 1;
 }
 
-static void cpackProgressCallback(const std::string& message, float /*unused*/)
+void cpackProgressCallback(const std::string& message, float /*unused*/)
 {
   std::cout << "-- " << message << std::endl;
 }
+} // namespace
 
 // this is CPack.
 int main(int argc, char const* const* argv)
@@ -268,7 +270,7 @@
     }
 
     if (!cpackBuildConfig.empty()) {
-      globalMF.AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str());
+      globalMF.AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig);
     }
 
     if (cmSystemTools::FileExists(cpackConfigFile)) {
@@ -290,24 +292,21 @@
     }
 
     if (!generator.empty()) {
-      globalMF.AddDefinition("CPACK_GENERATOR", generator.c_str());
+      globalMF.AddDefinition("CPACK_GENERATOR", generator);
     }
     if (!cpackProjectName.empty()) {
-      globalMF.AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName.c_str());
+      globalMF.AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName);
     }
     if (!cpackProjectVersion.empty()) {
-      globalMF.AddDefinition("CPACK_PACKAGE_VERSION",
-                             cpackProjectVersion.c_str());
+      globalMF.AddDefinition("CPACK_PACKAGE_VERSION", cpackProjectVersion);
     }
     if (!cpackProjectVendor.empty()) {
-      globalMF.AddDefinition("CPACK_PACKAGE_VENDOR",
-                             cpackProjectVendor.c_str());
+      globalMF.AddDefinition("CPACK_PACKAGE_VENDOR", cpackProjectVendor);
     }
     // if this is not empty it has been set on the command line
     // go for it. Command line override values set in config file.
     if (!cpackProjectDirectory.empty()) {
-      globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY",
-                             cpackProjectDirectory.c_str());
+      globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY", cpackProjectDirectory);
     }
     // The value has not been set on the command line
     else {
@@ -316,11 +315,11 @@
       // use default value iff no value has been provided by the config file
       if (!globalMF.IsSet("CPACK_PACKAGE_DIRECTORY")) {
         globalMF.AddDefinition("CPACK_PACKAGE_DIRECTORY",
-                               cpackProjectDirectory.c_str());
+                               cpackProjectDirectory);
       }
     }
     for (auto const& cd : definitions.Map) {
-      globalMF.AddDefinition(cd.first, cd.second.c_str());
+      globalMF.AddDefinition(cd.first, cd.second);
     }
 
     const char* cpackModulesPath = globalMF.GetDefinition("CPACK_MODULE_PATH");
@@ -424,7 +423,7 @@
               std::ostringstream ostr;
               ostr << projVersionMajor << "." << projVersionMinor << "."
                    << projVersionPatch;
-              mf->AddDefinition("CPACK_PACKAGE_VERSION", ostr.str().c_str());
+              mf->AddDefinition("CPACK_PACKAGE_VERSION", ostr.str());
             }
 
             int res = cpackGenerator->DoPackage();
diff --git a/Source/CTest/cmCTestBuildAndTestHandler.cxx b/Source/CTest/cmCTestBuildAndTestHandler.cxx
index 9ad9669..3aea1f4 100644
--- a/Source/CTest/cmCTestBuildAndTestHandler.cxx
+++ b/Source/CTest/cmCTestBuildAndTestHandler.cxx
@@ -76,6 +76,11 @@
   if (config) {
     args.push_back("-DCMAKE_BUILD_TYPE:STRING=" + std::string(config));
   }
+  if (!this->BuildMakeProgram.empty() &&
+      (this->BuildGenerator.find("Make") != std::string::npos ||
+       this->BuildGenerator.find("Ninja") != std::string::npos)) {
+    args.push_back("-DCMAKE_MAKE_PROGRAM:FILEPATH=" + this->BuildMakeProgram);
+  }
 
   for (std::string const& opt : this->BuildOptions) {
     args.push_back(opt);
diff --git a/Source/CTest/cmCTestBuildCommand.cxx b/Source/CTest/cmCTestBuildCommand.cxx
index 2eacaf1..e71eafe 100644
--- a/Source/CTest/cmCTestBuildCommand.cxx
+++ b/Source/CTest/cmCTestBuildCommand.cxx
@@ -156,15 +156,14 @@
   if (this->Values[ctb_NUMBER_ERRORS] && *this->Values[ctb_NUMBER_ERRORS]) {
     std::ostringstream str;
     str << this->Handler->GetTotalErrors();
-    this->Makefile->AddDefinition(this->Values[ctb_NUMBER_ERRORS],
-                                  str.str().c_str());
+    this->Makefile->AddDefinition(this->Values[ctb_NUMBER_ERRORS], str.str());
   }
   if (this->Values[ctb_NUMBER_WARNINGS] &&
       *this->Values[ctb_NUMBER_WARNINGS]) {
     std::ostringstream str;
     str << this->Handler->GetTotalWarnings();
     this->Makefile->AddDefinition(this->Values[ctb_NUMBER_WARNINGS],
-                                  str.str().c_str());
+                                  str.str());
   }
   return ret;
 }
diff --git a/Source/CTest/cmCTestBuildCommand.h b/Source/CTest/cmCTestBuildCommand.h
index 77b0549..a62c301 100644
--- a/Source/CTest/cmCTestBuildCommand.h
+++ b/Source/CTest/cmCTestBuildCommand.h
@@ -6,13 +6,16 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include "cmCTestHandlerCommand.h"
+#include "cmCommand.h"
 
 #include <string>
+#include <utility>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 class cmCTestBuildHandler;
 class cmCTestGenericHandler;
-class cmCommand;
 class cmExecutionStatus;
 class cmGlobalGenerator;
 
@@ -30,12 +33,12 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestBuildCommand* ni = new cmCTestBuildCommand;
+    auto ni = cm::make_unique<cmCTestBuildCommand>();
     ni->CTest = this->CTest;
     ni->CTestScriptHandler = this->CTestScriptHandler;
-    return ni;
+    return std::unique_ptr<cmCommand>(std::move(ni));
   }
 
   /**
diff --git a/Source/CTest/cmCTestConfigureCommand.h b/Source/CTest/cmCTestConfigureCommand.h
index 0cbcbfa..4677c83 100644
--- a/Source/CTest/cmCTestConfigureCommand.h
+++ b/Source/CTest/cmCTestConfigureCommand.h
@@ -6,11 +6,14 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include "cmCTestHandlerCommand.h"
+#include "cmCommand.h"
 
 #include <string>
+#include <utility>
+
+#include "cm_memory.hxx"
 
 class cmCTestGenericHandler;
-class cmCommand;
 
 /** \class cmCTestConfigure
  * \brief Run a ctest script
@@ -25,12 +28,12 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestConfigureCommand* ni = new cmCTestConfigureCommand;
+    auto ni = cm::make_unique<cmCTestConfigureCommand>();
     ni->CTest = this->CTest;
     ni->CTestScriptHandler = this->CTestScriptHandler;
-    return ni;
+    return std::unique_ptr<cmCommand>(std::move(ni));
   }
 
   /**
diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h
index 1ae2d86..08f31f7 100644
--- a/Source/CTest/cmCTestCoverageCommand.h
+++ b/Source/CTest/cmCTestCoverageCommand.h
@@ -6,12 +6,15 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include "cmCTestHandlerCommand.h"
+#include "cmCommand.h"
 
 #include <set>
 #include <string>
+#include <utility>
+
+#include "cm_memory.hxx"
 
 class cmCTestGenericHandler;
-class cmCommand;
 
 /** \class cmCTestCoverage
  * \brief Run a ctest script
@@ -26,12 +29,12 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestCoverageCommand* ni = new cmCTestCoverageCommand;
+    auto ni = cm::make_unique<cmCTestCoverageCommand>();
     ni->CTest = this->CTest;
     ni->CTestScriptHandler = this->CTestScriptHandler;
-    return ni;
+    return std::unique_ptr<cmCommand>(std::move(ni));
   }
 
   /**
diff --git a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
index 9425ece..84250cb 100644
--- a/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
+++ b/Source/CTest/cmCTestEmptyBinaryDirectoryCommand.h
@@ -6,11 +6,14 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include "cmCTestCommand.h"
+#include "cmCommand.h"
 
 #include <string>
+#include <utility>
 #include <vector>
 
-class cmCommand;
+#include "cm_memory.hxx"
+
 class cmExecutionStatus;
 
 /** \class cmCTestEmptyBinaryDirectory
@@ -27,13 +30,12 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestEmptyBinaryDirectoryCommand* ni =
-      new cmCTestEmptyBinaryDirectoryCommand;
+    auto ni = cm::make_unique<cmCTestEmptyBinaryDirectoryCommand>();
     ni->CTest = this->CTest;
     ni->CTestScriptHandler = this->CTestScriptHandler;
-    return ni;
+    return std::unique_ptr<cmCommand>(std::move(ni));
   }
 
   /**
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index adf9553..8ceca08 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -4,6 +4,7 @@
 
 #include "cmCTest.h"
 #include "cmCTestGenericHandler.h"
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmSystemTools.h"
@@ -13,8 +14,6 @@
 #include <sstream>
 #include <stdlib.h>
 
-class cmExecutionStatus;
-
 cmCTestHandlerCommand::cmCTestHandlerCommand()
 {
   const size_t INIT_SIZE = 100;
@@ -86,7 +85,7 @@
 }
 
 bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
-                                        cmExecutionStatus& /*unused*/)
+                                        cmExecutionStatus& status)
 {
   // save error state and restore it if needed
   SaveRestoreErrorState errorState;
@@ -113,20 +112,20 @@
       foundBadArgument = true;
     }
   }
-  bool capureCMakeError = (this->Values[ct_CAPTURE_CMAKE_ERROR] &&
-                           *this->Values[ct_CAPTURE_CMAKE_ERROR]);
+  bool captureCMakeError = (this->Values[ct_CAPTURE_CMAKE_ERROR] &&
+                            *this->Values[ct_CAPTURE_CMAKE_ERROR]);
   // now that arguments are parsed check to see if there is a
   // CAPTURE_CMAKE_ERROR specified let the errorState object know.
-  if (capureCMakeError) {
+  if (captureCMakeError) {
     errorState.CaptureCMakeError();
   }
   // if we found a bad argument then exit before running command
   if (foundBadArgument) {
     // store the cmake error
-    if (capureCMakeError) {
+    if (captureCMakeError) {
       this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
                                     "-1");
-      std::string const err = this->GetName() + " " + this->GetError();
+      std::string const err = this->GetName() + " " + status.GetError();
       if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
         cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n");
       }
@@ -192,11 +191,11 @@
     cmCTestLog(this->CTest, ERROR_MESSAGE,
                "Cannot instantiate test handler " << this->GetName()
                                                   << std::endl);
-    if (capureCMakeError) {
+    if (captureCMakeError) {
       this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
                                     "-1");
-      const char* err = this->GetError();
-      if (err && !cmSystemTools::FindLastString(err, "unknown error.")) {
+      std::string const& err = status.GetError();
+      if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
         cmCTestLog(this->CTest, ERROR_MESSAGE, err << " error from command\n");
       }
       return true;
@@ -216,11 +215,11 @@
     this->SetError("failed to change directory to " +
                    this->CTest->GetCTestConfiguration("BuildDirectory") +
                    " : " + std::strerror(workdir.GetLastResult()));
-    if (capureCMakeError) {
+    if (captureCMakeError) {
       this->Makefile->AddDefinition(this->Values[ct_CAPTURE_CMAKE_ERROR],
                                     "-1");
       cmCTestLog(this->CTest, ERROR_MESSAGE,
-                 this->GetName() << " " << this->GetError() << "\n");
+                 this->GetName() << " " << status.GetError() << "\n");
       // return success because failure is recorded in CAPTURE_CMAKE_ERROR
       return true;
     }
@@ -231,19 +230,18 @@
   if (this->Values[ct_RETURN_VALUE] && *this->Values[ct_RETURN_VALUE]) {
     std::ostringstream str;
     str << res;
-    this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE],
-                                  str.str().c_str());
+    this->Makefile->AddDefinition(this->Values[ct_RETURN_VALUE], str.str());
   }
   this->ProcessAdditionalValues(handler);
   // log the error message if there was an error
-  if (capureCMakeError) {
+  if (captureCMakeError) {
     const char* returnString = "0";
     if (cmSystemTools::GetErrorOccuredFlag()) {
       returnString = "-1";
-      const char* err = this->GetError();
+      std::string const& err = status.GetError();
       // print out the error if it is not "unknown error" which means
       // there was no message
-      if (err && !cmSystemTools::FindLastString(err, "unknown error.")) {
+      if (!cmSystemTools::FindLastString(err.c_str(), "unknown error.")) {
         cmCTestLog(this->CTest, ERROR_MESSAGE, err);
       }
     }
diff --git a/Source/CTest/cmCTestMemCheckCommand.cxx b/Source/CTest/cmCTestMemCheckCommand.cxx
index 7dad1ce..d7d42bf 100644
--- a/Source/CTest/cmCTestMemCheckCommand.cxx
+++ b/Source/CTest/cmCTestMemCheckCommand.cxx
@@ -3,7 +3,6 @@
 #include "cmCTestMemCheckCommand.h"
 
 #include <sstream>
-#include <string>
 #include <vector>
 
 #include "cmCTest.h"
@@ -47,7 +46,6 @@
   if (this->Values[ctm_DEFECT_COUNT] && *this->Values[ctm_DEFECT_COUNT]) {
     std::ostringstream str;
     str << static_cast<cmCTestMemCheckHandler*>(handler)->GetDefectCount();
-    this->Makefile->AddDefinition(this->Values[ctm_DEFECT_COUNT],
-                                  str.str().c_str());
+    this->Makefile->AddDefinition(this->Values[ctm_DEFECT_COUNT], str.str());
   }
 }
diff --git a/Source/CTest/cmCTestMemCheckCommand.h b/Source/CTest/cmCTestMemCheckCommand.h
index b6b3c40..837a687 100644
--- a/Source/CTest/cmCTestMemCheckCommand.h
+++ b/Source/CTest/cmCTestMemCheckCommand.h
@@ -5,10 +5,14 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <utility>
+
+#include "cm_memory.hxx"
+
 #include "cmCTestTestCommand.h"
+#include "cmCommand.h"
 
 class cmCTestGenericHandler;
-class cmCommand;
 
 /** \class cmCTestMemCheck
  * \brief Run a ctest script
@@ -23,12 +27,12 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestMemCheckCommand* ni = new cmCTestMemCheckCommand;
+    auto ni = cm::make_unique<cmCTestMemCheckCommand>();
     ni->CTest = this->CTest;
     ni->CTestScriptHandler = this->CTestScriptHandler;
-    return ni;
+    return std::unique_ptr<cmCommand>(std::move(ni));
   }
 
 protected:
diff --git a/Source/CTest/cmCTestMultiProcessHandler.cxx b/Source/CTest/cmCTestMultiProcessHandler.cxx
index 37a8abf..42534f7 100644
--- a/Source/CTest/cmCTestMultiProcessHandler.cxx
+++ b/Source/CTest/cmCTestMultiProcessHandler.cxx
@@ -823,6 +823,11 @@
       "FAIL_REGULAR_EXPRESSION",
       DumpRegExToJsonArray(testProperties.ErrorRegularExpressions)));
   }
+  if (!testProperties.SkipRegularExpressions.empty()) {
+    properties.append(DumpCTestProperty(
+      "SKIP_REGULAR_EXPRESSION",
+      DumpRegExToJsonArray(testProperties.SkipRegularExpressions)));
+  }
   if (!testProperties.FixturesCleanup.empty()) {
     properties.append(DumpCTestProperty(
       "FIXTURES_CLEANUP", DumpToJsonArray(testProperties.FixturesCleanup)));
diff --git a/Source/CTest/cmCTestReadCustomFilesCommand.h b/Source/CTest/cmCTestReadCustomFilesCommand.h
index ba25c51..db2ac5e 100644
--- a/Source/CTest/cmCTestReadCustomFilesCommand.h
+++ b/Source/CTest/cmCTestReadCustomFilesCommand.h
@@ -6,11 +6,14 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include "cmCTestCommand.h"
+#include "cmCommand.h"
 
 #include <string>
+#include <utility>
 #include <vector>
 
-class cmCommand;
+#include "cm_memory.hxx"
+
 class cmExecutionStatus;
 
 /** \class cmCTestReadCustomFiles
@@ -27,11 +30,11 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestReadCustomFilesCommand* ni = new cmCTestReadCustomFilesCommand;
+    auto ni = cm::make_unique<cmCTestReadCustomFilesCommand>();
     ni->CTest = this->CTest;
-    return ni;
+    return std::unique_ptr<cmCommand>(std::move(ni));
   }
 
   /**
diff --git a/Source/CTest/cmCTestRunScriptCommand.cxx b/Source/CTest/cmCTestRunScriptCommand.cxx
index a7e47d3..c03cffd 100644
--- a/Source/CTest/cmCTestRunScriptCommand.cxx
+++ b/Source/CTest/cmCTestRunScriptCommand.cxx
@@ -43,7 +43,7 @@
                                       args[i].c_str(), !np, &ret);
       std::ostringstream str;
       str << ret;
-      this->Makefile->AddDefinition(returnVariable, str.str().c_str());
+      this->Makefile->AddDefinition(returnVariable, str.str());
     }
   }
   return true;
diff --git a/Source/CTest/cmCTestRunScriptCommand.h b/Source/CTest/cmCTestRunScriptCommand.h
index 9d8b4b5..6961f6e 100644
--- a/Source/CTest/cmCTestRunScriptCommand.h
+++ b/Source/CTest/cmCTestRunScriptCommand.h
@@ -6,11 +6,14 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include "cmCTestCommand.h"
+#include "cmCommand.h"
 
 #include <string>
+#include <utility>
 #include <vector>
 
-class cmCommand;
+#include "cm_memory.hxx"
+
 class cmExecutionStatus;
 
 /** \class cmCTestRunScript
@@ -27,12 +30,12 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestRunScriptCommand* ni = new cmCTestRunScriptCommand;
+    auto ni = cm::make_unique<cmCTestRunScriptCommand>();
     ni->CTest = this->CTest;
     ni->CTestScriptHandler = this->CTestScriptHandler;
-    return ni;
+    return std::unique_ptr<cmCommand>(std::move(ni));
   }
 
   /**
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index b865cab..65cf646 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -11,7 +11,6 @@
 
 #include "cmsys/RegularExpression.hxx"
 #include <chrono>
-#include <cmAlgorithms.h>
 #include <cstdint>
 #include <cstring>
 #include <iomanip>
@@ -20,6 +19,8 @@
 #include <stdio.h>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 cmCTestRunTest::cmCTestRunTest(cmCTestMultiProcessHandler& multiHandler)
   : MultiTestHandler(multiHandler)
 {
@@ -76,6 +77,7 @@
   }
   std::int64_t retVal = this->TestProcess->GetExitValue();
   bool forceFail = false;
+  bool forceSkip = false;
   bool skipped = false;
   bool outputTestErrorsToConsole = false;
   if (!this->TestProperties->RequiredRegularExpressions.empty() &&
@@ -115,16 +117,34 @@
       }
     }
   }
+  if (!this->TestProperties->SkipRegularExpressions.empty() &&
+      this->FailedDependencies.empty()) {
+    for (auto& skip : this->TestProperties->SkipRegularExpressions) {
+      if (skip.first.find(this->ProcessOutput)) {
+        reason = "Skip regular expression found in output.";
+        reason += " Regex=[";
+        reason += skip.second;
+        reason += "]";
+        forceSkip = true;
+        break;
+      }
+    }
+  }
   std::ostringstream outputStream;
   if (res == cmProcess::State::Exited) {
     bool success = !forceFail &&
       (retVal == 0 ||
        !this->TestProperties->RequiredRegularExpressions.empty());
-    if (this->TestProperties->SkipReturnCode >= 0 &&
-        this->TestProperties->SkipReturnCode == retVal) {
+    if ((this->TestProperties->SkipReturnCode >= 0 &&
+         this->TestProperties->SkipReturnCode == retVal) ||
+        forceSkip) {
       this->TestResult.Status = cmCTestTestHandler::NOT_RUN;
       std::ostringstream s;
-      s << "SKIP_RETURN_CODE=" << this->TestProperties->SkipReturnCode;
+      if (forceSkip) {
+        s << "SKIP_REGULAR_EXPRESSION_MATCHED";
+      } else {
+        s << "SKIP_RETURN_CODE=" << this->TestProperties->SkipReturnCode;
+      }
       this->TestResult.CompletionStatus = s.str();
       cmCTestLog(this->CTest, HANDLER_OUTPUT, "***Skipped ");
       skipped = true;
diff --git a/Source/CTest/cmCTestScriptHandler.cxx b/Source/CTest/cmCTestScriptHandler.cxx
index a739f44..7a5b8d1 100644
--- a/Source/CTest/cmCTestScriptHandler.cxx
+++ b/Source/CTest/cmCTestScriptHandler.cxx
@@ -4,13 +4,8 @@
 
 #include "cmsys/Directory.hxx"
 #include "cmsys/Process.h"
-#include <map>
-#include <ratio>
-#include <sstream>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <utility>
+
+#include "cm_memory.hxx"
 
 #include "cmCTest.h"
 #include "cmCTestBuildCommand.h"
@@ -27,6 +22,7 @@
 #include "cmCTestTestCommand.h"
 #include "cmCTestUpdateCommand.h"
 #include "cmCTestUploadCommand.h"
+#include "cmCommand.h"
 #include "cmDuration.h"
 #include "cmFunctionBlocker.h"
 #include "cmGeneratedFileStream.h"
@@ -38,6 +34,15 @@
 #include "cmSystemTools.h"
 #include "cmake.h"
 
+#include <map>
+#include <memory>
+#include <ratio>
+#include <sstream>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <utility>
+
 #ifdef _WIN32
 #  include <windows.h>
 #else
@@ -163,16 +168,16 @@
     auto itime = cmDurationTo<unsigned int>(std::chrono::steady_clock::now() -
                                             this->ScriptStartTime);
     auto timeString = std::to_string(itime);
-    this->Makefile->AddDefinition("CTEST_ELAPSED_TIME", timeString.c_str());
+    this->Makefile->AddDefinition("CTEST_ELAPSED_TIME", timeString);
   }
 }
 
-void cmCTestScriptHandler::AddCTestCommand(std::string const& name,
-                                           cmCTestCommand* command)
+void cmCTestScriptHandler::AddCTestCommand(
+  std::string const& name, std::unique_ptr<cmCTestCommand> command)
 {
   command->CTest = this->CTest;
   command->CTestScriptHandler = this;
-  this->CMake->GetState()->AddBuiltinCommand(name, command);
+  this->CMake->GetState()->AddBuiltinCommand(name, std::move(command));
 }
 
 int cmCTestScriptHandler::ExecuteScript(const std::string& total_script_arg)
@@ -295,21 +300,28 @@
       }
     });
 
-  this->AddCTestCommand("ctest_build", new cmCTestBuildCommand);
-  this->AddCTestCommand("ctest_configure", new cmCTestConfigureCommand);
-  this->AddCTestCommand("ctest_coverage", new cmCTestCoverageCommand);
+  this->AddCTestCommand("ctest_build", cm::make_unique<cmCTestBuildCommand>());
+  this->AddCTestCommand("ctest_configure",
+                        cm::make_unique<cmCTestConfigureCommand>());
+  this->AddCTestCommand("ctest_coverage",
+                        cm::make_unique<cmCTestCoverageCommand>());
   this->AddCTestCommand("ctest_empty_binary_directory",
-                        new cmCTestEmptyBinaryDirectoryCommand);
-  this->AddCTestCommand("ctest_memcheck", new cmCTestMemCheckCommand);
+                        cm::make_unique<cmCTestEmptyBinaryDirectoryCommand>());
+  this->AddCTestCommand("ctest_memcheck",
+                        cm::make_unique<cmCTestMemCheckCommand>());
   this->AddCTestCommand("ctest_read_custom_files",
-                        new cmCTestReadCustomFilesCommand);
-  this->AddCTestCommand("ctest_run_script", new cmCTestRunScriptCommand);
-  this->AddCTestCommand("ctest_sleep", new cmCTestSleepCommand);
-  this->AddCTestCommand("ctest_start", new cmCTestStartCommand);
-  this->AddCTestCommand("ctest_submit", new cmCTestSubmitCommand);
-  this->AddCTestCommand("ctest_test", new cmCTestTestCommand);
-  this->AddCTestCommand("ctest_update", new cmCTestUpdateCommand);
-  this->AddCTestCommand("ctest_upload", new cmCTestUploadCommand);
+                        cm::make_unique<cmCTestReadCustomFilesCommand>());
+  this->AddCTestCommand("ctest_run_script",
+                        cm::make_unique<cmCTestRunScriptCommand>());
+  this->AddCTestCommand("ctest_sleep", cm::make_unique<cmCTestSleepCommand>());
+  this->AddCTestCommand("ctest_start", cm::make_unique<cmCTestStartCommand>());
+  this->AddCTestCommand("ctest_submit",
+                        cm::make_unique<cmCTestSubmitCommand>());
+  this->AddCTestCommand("ctest_test", cm::make_unique<cmCTestTestCommand>());
+  this->AddCTestCommand("ctest_update",
+                        cm::make_unique<cmCTestUpdateCommand>());
+  this->AddCTestCommand("ctest_upload",
+                        cm::make_unique<cmCTestUploadCommand>());
 }
 
 // this sets up some variables for the script to use, creates the required
@@ -340,21 +352,21 @@
   this->CreateCMake();
 
   // set a variable with the path to the current script
-  this->Makefile->AddDefinition(
-    "CTEST_SCRIPT_DIRECTORY", cmSystemTools::GetFilenamePath(script).c_str());
-  this->Makefile->AddDefinition(
-    "CTEST_SCRIPT_NAME", cmSystemTools::GetFilenameName(script).c_str());
+  this->Makefile->AddDefinition("CTEST_SCRIPT_DIRECTORY",
+                                cmSystemTools::GetFilenamePath(script));
+  this->Makefile->AddDefinition("CTEST_SCRIPT_NAME",
+                                cmSystemTools::GetFilenameName(script));
   this->Makefile->AddDefinition("CTEST_EXECUTABLE_NAME",
-                                cmSystemTools::GetCTestCommand().c_str());
+                                cmSystemTools::GetCTestCommand());
   this->Makefile->AddDefinition("CMAKE_EXECUTABLE_NAME",
-                                cmSystemTools::GetCMakeCommand().c_str());
-  this->Makefile->AddDefinition("CTEST_RUN_CURRENT_SCRIPT", true);
+                                cmSystemTools::GetCMakeCommand());
+  this->Makefile->AddDefinitionBool("CTEST_RUN_CURRENT_SCRIPT", true);
   this->SetRunCurrentScript(true);
   this->UpdateElapsedTime();
 
   // add the script arg if defined
   if (!script_arg.empty()) {
-    this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg.c_str());
+    this->Makefile->AddDefinition("CTEST_SCRIPT_ARG", script_arg);
   }
 
 #if defined(__CYGWIN__)
@@ -362,9 +374,11 @@
 #endif
 
   // always add a function blocker to update the elapsed time
-  cmCTestScriptFunctionBlocker* f = new cmCTestScriptFunctionBlocker();
-  f->CTestScriptHandler = this;
-  this->Makefile->AddFunctionBlocker(f);
+  {
+    auto fb = cm::make_unique<cmCTestScriptFunctionBlocker>();
+    fb->CTestScriptHandler = this;
+    this->Makefile->AddFunctionBlocker(std::move(fb));
+  }
 
   /* Execute CTestScriptMode.cmake, which loads CMakeDetermineSystem and
   CMakeSystemSpecificInformation, so
@@ -384,7 +398,7 @@
   const std::map<std::string, std::string>& defs =
     this->CTest->GetDefinitions();
   for (auto const& d : defs) {
-    this->Makefile->AddDefinition(d.first, d.second.c_str());
+    this->Makefile->AddDefinition(d.first, d.second);
   }
 
   // finally read in the script
diff --git a/Source/CTest/cmCTestScriptHandler.h b/Source/CTest/cmCTestScriptHandler.h
index d93b5f8..b2e8cbf 100644
--- a/Source/CTest/cmCTestScriptHandler.h
+++ b/Source/CTest/cmCTestScriptHandler.h
@@ -9,6 +9,7 @@
 #include "cmDuration.h"
 
 #include <chrono>
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -131,7 +132,8 @@
   int RunConfigurationDashboard();
 
   // Add ctest command
-  void AddCTestCommand(std::string const& name, cmCTestCommand* command);
+  void AddCTestCommand(std::string const& name,
+                       std::unique_ptr<cmCTestCommand> command);
 
   // Try to remove the binary directory once
   static bool TryToRemoveBinaryDirectoryOnce(const std::string& directoryPath);
diff --git a/Source/CTest/cmCTestSleepCommand.h b/Source/CTest/cmCTestSleepCommand.h
index 5cd185a..7b17081 100644
--- a/Source/CTest/cmCTestSleepCommand.h
+++ b/Source/CTest/cmCTestSleepCommand.h
@@ -6,11 +6,14 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include "cmCTestCommand.h"
+#include "cmCommand.h"
 
 #include <string>
+#include <utility>
 #include <vector>
 
-class cmCommand;
+#include "cm_memory.hxx"
+
 class cmExecutionStatus;
 
 /** \class cmCTestSleep
@@ -27,12 +30,12 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestSleepCommand* ni = new cmCTestSleepCommand;
+    auto ni = cm::make_unique<cmCTestSleepCommand>();
     ni->CTest = this->CTest;
     ni->CTestScriptHandler = this->CTestScriptHandler;
-    return ni;
+    return std::unique_ptr<cmCommand>(std::move(ni));
   }
 
   /**
diff --git a/Source/CTest/cmCTestStartCommand.h b/Source/CTest/cmCTestStartCommand.h
index 542f27c..7c71f36 100644
--- a/Source/CTest/cmCTestStartCommand.h
+++ b/Source/CTest/cmCTestStartCommand.h
@@ -6,12 +6,15 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include "cmCTestCommand.h"
+#include "cmCommand.h"
 
 #include <iosfwd>
 #include <string>
+#include <utility>
 #include <vector>
 
-class cmCommand;
+#include "cm_memory.hxx"
+
 class cmExecutionStatus;
 
 /** \class cmCTestStart
@@ -27,14 +30,14 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestStartCommand* ni = new cmCTestStartCommand;
+    auto ni = cm::make_unique<cmCTestStartCommand>();
     ni->CTest = this->CTest;
     ni->CTestScriptHandler = this->CTestScriptHandler;
     ni->CreateNewTag = this->CreateNewTag;
     ni->Quiet = this->Quiet;
-    return ni;
+    return std::unique_ptr<cmCommand>(std::move(ni));
   }
 
   /**
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index afc3e67..58c0a1b 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -4,11 +4,15 @@
 
 #include "cmCTest.h"
 #include "cmCTestSubmitHandler.h"
+#include "cmCommand.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
 #include "cmSystemTools.h"
 
 #include <sstream>
+#include <utility>
+
+#include "cm_memory.hxx"
 
 class cmExecutionStatus;
 
@@ -27,12 +31,12 @@
 /**
  * This is a virtual constructor for the command.
  */
-cmCommand* cmCTestSubmitCommand::Clone()
+std::unique_ptr<cmCommand> cmCTestSubmitCommand::Clone()
 {
-  cmCTestSubmitCommand* ni = new cmCTestSubmitCommand;
+  auto ni = cm::make_unique<cmCTestSubmitCommand>();
   ni->CTest = this->CTest;
   ni->CTestScriptHandler = this->CTestScriptHandler;
-  return ni;
+  return std::unique_ptr<cmCommand>(std::move(ni));
 }
 
 cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
@@ -139,7 +143,7 @@
 
   if (this->Values[cts_BUILD_ID] && *this->Values[cts_BUILD_ID]) {
     this->Makefile->AddDefinition(this->Values[cts_BUILD_ID],
-                                  this->CTest->GetBuildID().c_str());
+                                  this->CTest->GetBuildID());
   }
 
   return ret;
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
index 1e27046..5bbcd39 100644
--- a/Source/CTest/cmCTestSubmitCommand.h
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -8,12 +8,13 @@
 #include "cmCTest.h"
 #include "cmCTestHandlerCommand.h"
 
+#include <memory>
 #include <set>
 #include <string>
 #include <vector>
 
-class cmCTestGenericHandler;
 class cmCommand;
+class cmCTestGenericHandler;
 class cmExecutionStatus;
 
 /** \class cmCTestSubmit
@@ -26,7 +27,7 @@
 {
 public:
   cmCTestSubmitCommand();
-  cmCommand* Clone() override;
+  std::unique_ptr<cmCommand> Clone() override;
 
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
diff --git a/Source/CTest/cmCTestSubmitHandler.cxx b/Source/CTest/cmCTestSubmitHandler.cxx
index 1fa7988..54c4bae 100644
--- a/Source/CTest/cmCTestSubmitHandler.cxx
+++ b/Source/CTest/cmCTestSubmitHandler.cxx
@@ -266,15 +266,6 @@
         }
       }
 
-      upload_as += "&MD5=";
-
-      if (cmSystemTools::IsOn(this->GetOption("InternalTest"))) {
-        upload_as += "bad_md5sum";
-      } else {
-        upload_as +=
-          cmSystemTools::ComputeFileHash(local_file, cmCryptoHash::AlgoMD5);
-      }
-
       // Generate Done.xml right before it is submitted.
       // The reason for this is two-fold:
       // 1) It must be generated after some other part has been submitted
@@ -286,6 +277,15 @@
         this->CTest->GenerateDoneFile();
       }
 
+      upload_as += "&MD5=";
+
+      if (cmSystemTools::IsOn(this->GetOption("InternalTest"))) {
+        upload_as += "bad_md5sum";
+      } else {
+        upload_as +=
+          cmSystemTools::ComputeFileHash(local_file, cmCryptoHash::AlgoMD5);
+      }
+
       if (!cmSystemTools::FileExists(local_file)) {
         cmCTestLog(this->CTest, ERROR_MESSAGE,
                    "   Cannot find file: " << local_file << std::endl);
diff --git a/Source/CTest/cmCTestTestCommand.h b/Source/CTest/cmCTestTestCommand.h
index 11c0db9..d74136c 100644
--- a/Source/CTest/cmCTestTestCommand.h
+++ b/Source/CTest/cmCTestTestCommand.h
@@ -6,11 +6,14 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include "cmCTestHandlerCommand.h"
+#include "cmCommand.h"
 
 #include <string>
+#include <utility>
+
+#include "cm_memory.hxx"
 
 class cmCTestGenericHandler;
-class cmCommand;
 
 /** \class cmCTestTest
  * \brief Run a ctest script
@@ -25,12 +28,12 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestTestCommand* ni = new cmCTestTestCommand;
+    auto ni = cm::make_unique<cmCTestTestCommand>();
     ni->CTest = this->CTest;
     ni->CTestScriptHandler = this->CTestScriptHandler;
-    return ni;
+    return std::unique_ptr<cmCommand>(std::move(ni));
   }
 
   /**
diff --git a/Source/CTest/cmCTestTestHandler.cxx b/Source/CTest/cmCTestTestHandler.cxx
index 46ef809..5134407 100644
--- a/Source/CTest/cmCTestTestHandler.cxx
+++ b/Source/CTest/cmCTestTestHandler.cxx
@@ -11,12 +11,14 @@
 #include <functional>
 #include <iomanip>
 #include <iterator>
-#include <memory>
 #include <set>
 #include <sstream>
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
+#include <utility>
+
+#include "cm_memory.hxx"
 
 #include "cmAlgorithms.h"
 #include "cmCTest.h"
@@ -43,11 +45,11 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestSubdirCommand* c = new cmCTestSubdirCommand;
+    auto c = cm::make_unique<cmCTestSubdirCommand>();
     c->TestHandler = this->TestHandler;
-    return c;
+    return std::unique_ptr<cmCommand>(std::move(c));
   }
 
   /**
@@ -122,11 +124,11 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestAddSubdirectoryCommand* c = new cmCTestAddSubdirectoryCommand;
+    auto c = cm::make_unique<cmCTestAddSubdirectoryCommand>();
     c->TestHandler = this->TestHandler;
-    return c;
+    return std::unique_ptr<cmCommand>(std::move(c));
   }
 
   /**
@@ -187,11 +189,11 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestAddTestCommand* c = new cmCTestAddTestCommand;
+    auto c = cm::make_unique<cmCTestAddTestCommand>();
     c->TestHandler = this->TestHandler;
-    return c;
+    return std::unique_ptr<cmCommand>(std::move(c));
   }
 
   /**
@@ -220,11 +222,11 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestSetTestsPropertiesCommand* c = new cmCTestSetTestsPropertiesCommand;
+    auto c = cm::make_unique<cmCTestSetTestsPropertiesCommand>();
     c->TestHandler = this->TestHandler;
-    return c;
+    return std::unique_ptr<cmCommand>(std::move(c));
   }
 
   /**
@@ -249,12 +251,11 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestSetDirectoryPropertiesCommand* c =
-      new cmCTestSetDirectoryPropertiesCommand;
+    auto c = cm::make_unique<cmCTestSetDirectoryPropertiesCommand>();
     c->TestHandler = this->TestHandler;
-    return c;
+    return std::unique_ptr<cmCommand>(std::move(c));
   }
 
   /**
@@ -422,10 +423,93 @@
   return 1;
 }
 
-// clearly it would be nice if this were broken up into a few smaller
-// functions and commented...
 int cmCTestTestHandler::ProcessHandler()
 {
+  if (!this->ProcessOptions()) {
+    return -1;
+  }
+
+  this->TestResults.clear();
+
+  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+                     (this->MemCheck ? "Memory check" : "Test")
+                       << " project "
+                       << cmSystemTools::GetCurrentWorkingDirectory()
+                       << std::endl,
+                     this->Quiet);
+  if (!this->PreProcessHandler()) {
+    return -1;
+  }
+
+  cmGeneratedFileStream mLogFile;
+  this->StartLogFile((this->MemCheck ? "DynamicAnalysis" : "Test"), mLogFile);
+  this->LogFile = &mLogFile;
+
+  std::vector<std::string> passed;
+  std::vector<std::string> failed;
+
+  // start the real time clock
+  auto clock_start = std::chrono::steady_clock::now();
+
+  this->ProcessDirectory(passed, failed);
+
+  auto clock_finish = std::chrono::steady_clock::now();
+
+  if (passed.size() + failed.size() == 0) {
+    if (!this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels()) {
+      cmCTestLog(this->CTest, ERROR_MESSAGE,
+                 "No tests were found!!!" << std::endl);
+    }
+  } else {
+    if (this->HandlerVerbose && !passed.empty() &&
+        (this->UseIncludeRegExpFlag || this->UseExcludeRegExpFlag)) {
+      cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+                         std::endl
+                           << "The following tests passed:" << std::endl,
+                         this->Quiet);
+      for (std::string const& j : passed) {
+        cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
+                           "\t" << j << std::endl, this->Quiet);
+      }
+    }
+
+    SetOfTests resultsSet(this->TestResults.begin(), this->TestResults.end());
+    std::vector<cmCTestTestHandler::cmCTestTestResult> disabledTests;
+
+    for (cmCTestTestResult const& ft : resultsSet) {
+      if (cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_") ||
+          ft.CompletionStatus == "Disabled") {
+        disabledTests.push_back(ft);
+      }
+    }
+
+    cmDuration durationInSecs = clock_finish - clock_start;
+    this->LogTestSummary(passed, failed, durationInSecs);
+
+    this->LogDisabledTests(disabledTests);
+
+    this->LogFailedTests(failed, resultsSet);
+  }
+
+  if (!this->GenerateXML()) {
+    return 1;
+  }
+
+  if (!this->PostProcessHandler()) {
+    this->LogFile = nullptr;
+    return -1;
+  }
+
+  if (!failed.empty()) {
+    this->LogFile = nullptr;
+    return -1;
+  }
+  this->LogFile = nullptr;
+  return 0;
+}
+
+bool cmCTestTestHandler::ProcessOptions()
+{
   // Update internal data structure from generic one
   this->SetTestsToRunInformation(this->GetOption("TestsToRunInformation"));
   this->SetUseUnion(cmSystemTools::IsOn(this->GetOption("UseUnion")));
@@ -471,152 +555,110 @@
   }
   this->SetRerunFailed(cmSystemTools::IsOn(this->GetOption("RerunFailed")));
 
-  this->TestResults.clear();
+  return true;
+}
 
-  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
-                     (this->MemCheck ? "Memory check" : "Test")
-                       << " project "
-                       << cmSystemTools::GetCurrentWorkingDirectory()
-                       << std::endl,
-                     this->Quiet);
-  if (!this->PreProcessHandler()) {
-    return -1;
+void cmCTestTestHandler::LogTestSummary(const std::vector<std::string>& passed,
+                                        const std::vector<std::string>& failed,
+                                        const cmDuration& durationInSecs)
+{
+  std::size_t total = passed.size() + failed.size();
+
+  float percent = float(passed.size()) * 100.0f / float(total);
+  if (!failed.empty() && percent > 99) {
+    percent = 99;
   }
 
-  cmGeneratedFileStream mLogFile;
-  this->StartLogFile((this->MemCheck ? "DynamicAnalysis" : "Test"), mLogFile);
-  this->LogFile = &mLogFile;
-
-  std::vector<std::string> passed;
-  std::vector<std::string> failed;
-  int total;
-
-  // start the real time clock
-  auto clock_start = std::chrono::steady_clock::now();
-
-  this->ProcessDirectory(passed, failed);
-
-  auto clock_finish = std::chrono::steady_clock::now();
-
-  total = int(passed.size()) + int(failed.size());
-
-  if (total == 0) {
-    if (!this->CTest->GetShowOnly() && !this->CTest->ShouldPrintLabels()) {
-      cmCTestLog(this->CTest, ERROR_MESSAGE,
-                 "No tests were found!!!" << std::endl);
-    }
+  std::string passColorCode;
+  std::string failedColorCode;
+  if (failed.empty()) {
+    passColorCode = this->CTest->GetColorCode(cmCTest::Color::GREEN);
   } else {
-    if (this->HandlerVerbose && !passed.empty() &&
-        (this->UseIncludeRegExpFlag || this->UseExcludeRegExpFlag)) {
-      cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
-                         std::endl
-                           << "The following tests passed:" << std::endl,
-                         this->Quiet);
-      for (std::string const& j : passed) {
-        cmCTestOptionalLog(this->CTest, HANDLER_VERBOSE_OUTPUT,
-                           "\t" << j << std::endl, this->Quiet);
-      }
-    }
+    failedColorCode = this->CTest->GetColorCode(cmCTest::Color::RED);
+  }
+  cmCTestLog(this->CTest, HANDLER_OUTPUT,
+             std::endl
+               << passColorCode << std::lround(percent) << "% tests passed"
+               << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
+               << ", " << failedColorCode << failed.size() << " tests failed"
+               << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
+               << " out of " << total << std::endl);
+  if ((!this->CTest->GetLabelsForSubprojects().empty() &&
+       this->CTest->GetSubprojectSummary())) {
+    this->PrintLabelOrSubprojectSummary(true);
+  }
+  if (this->CTest->GetLabelSummary()) {
+    this->PrintLabelOrSubprojectSummary(false);
+  }
+  char realBuf[1024];
+  sprintf(realBuf, "%6.2f sec", durationInSecs.count());
+  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
+                     "\nTotal Test time (real) = " << realBuf << "\n",
+                     this->Quiet);
+}
 
-    typedef std::set<cmCTestTestHandler::cmCTestTestResult,
-                     cmCTestTestResultLess>
-      SetOfTests;
-    SetOfTests resultsSet(this->TestResults.begin(), this->TestResults.end());
-    std::vector<cmCTestTestHandler::cmCTestTestResult> disabledTests;
-
-    for (cmCTestTestResult const& ft : resultsSet) {
-      if (cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_RETURN_CODE=") ||
-          ft.CompletionStatus == "Disabled") {
-        disabledTests.push_back(ft);
-      }
-    }
-
-    float percent = float(passed.size()) * 100.0f / float(total);
-    if (!failed.empty() && percent > 99) {
-      percent = 99;
-    }
-
-    std::string passColorCode;
-    std::string failedColorCode;
-    if (failed.empty()) {
-      passColorCode = this->CTest->GetColorCode(cmCTest::Color::GREEN);
-    } else {
-      failedColorCode = this->CTest->GetColorCode(cmCTest::Color::RED);
-    }
+void cmCTestTestHandler::LogDisabledTests(
+  const std::vector<cmCTestTestResult>& disabledTests)
+{
+  if (!disabledTests.empty()) {
+    cmGeneratedFileStream ofs;
     cmCTestLog(this->CTest, HANDLER_OUTPUT,
                std::endl
-                 << passColorCode << std::lround(percent) << "% tests passed"
-                 << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
-                 << ", " << failedColorCode << failed.size() << " tests failed"
-                 << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
-                 << " out of " << total << std::endl);
-    if ((!this->CTest->GetLabelsForSubprojects().empty() &&
-         this->CTest->GetSubprojectSummary())) {
-      this->PrintLabelOrSubprojectSummary(true);
-    }
-    if (this->CTest->GetLabelSummary()) {
-      this->PrintLabelOrSubprojectSummary(false);
-    }
-    char realBuf[1024];
-    cmDuration durationInSecs = clock_finish - clock_start;
-    sprintf(realBuf, "%6.2f sec", durationInSecs.count());
-    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
-                       "\nTotal Test time (real) = " << realBuf << "\n",
-                       this->Quiet);
+                 << "The following tests did not run:" << std::endl);
+    this->StartLogFile("TestsDisabled", ofs);
 
-    if (!disabledTests.empty()) {
-      cmGeneratedFileStream ofs;
-      cmCTestLog(this->CTest, HANDLER_OUTPUT,
-                 std::endl
-                   << "The following tests did not run:" << std::endl);
-      this->StartLogFile("TestsDisabled", ofs);
-
-      const char* disabled_reason;
-      cmCTestLog(this->CTest, HANDLER_OUTPUT,
-                 this->CTest->GetColorCode(cmCTest::Color::BLUE));
-      for (cmCTestTestResult const& dt : disabledTests) {
-        ofs << dt.TestCount << ":" << dt.Name << std::endl;
-        if (dt.CompletionStatus == "Disabled") {
-          disabled_reason = "Disabled";
-        } else {
-          disabled_reason = "Skipped";
-        }
-        cmCTestLog(this->CTest, HANDLER_OUTPUT,
-                   "\t" << std::setw(3) << dt.TestCount << " - " << dt.Name
-                        << " (" << disabled_reason << ")" << std::endl);
+    const char* disabled_reason;
+    cmCTestLog(this->CTest, HANDLER_OUTPUT,
+               this->CTest->GetColorCode(cmCTest::Color::BLUE));
+    for (cmCTestTestResult const& dt : disabledTests) {
+      ofs << dt.TestCount << ":" << dt.Name << std::endl;
+      if (dt.CompletionStatus == "Disabled") {
+        disabled_reason = "Disabled";
+      } else {
+        disabled_reason = "Skipped";
       }
       cmCTestLog(this->CTest, HANDLER_OUTPUT,
-                 this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR));
+                 "\t" << std::setw(3) << dt.TestCount << " - " << dt.Name
+                      << " (" << disabled_reason << ")" << std::endl);
     }
+    cmCTestLog(this->CTest, HANDLER_OUTPUT,
+               this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR));
+  }
+}
 
-    if (!failed.empty()) {
-      cmGeneratedFileStream ofs;
-      cmCTestLog(this->CTest, HANDLER_OUTPUT,
-                 std::endl
-                   << "The following tests FAILED:" << std::endl);
-      this->StartLogFile("TestsFailed", ofs);
+void cmCTestTestHandler::LogFailedTests(const std::vector<std::string>& failed,
+                                        const SetOfTests& resultsSet)
+{
+  if (!failed.empty()) {
+    cmGeneratedFileStream ofs;
+    cmCTestLog(this->CTest, HANDLER_OUTPUT,
+               std::endl
+                 << "The following tests FAILED:" << std::endl);
+    this->StartLogFile("TestsFailed", ofs);
 
-      for (cmCTestTestResult const& ft : resultsSet) {
-        if (ft.Status != cmCTestTestHandler::COMPLETED &&
-            !cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_RETURN_CODE=") &&
-            ft.CompletionStatus != "Disabled") {
-          ofs << ft.TestCount << ":" << ft.Name << std::endl;
-          auto testColor = cmCTest::Color::RED;
-          if (this->GetTestStatus(ft) == "Not Run") {
-            testColor = cmCTest::Color::YELLOW;
-          }
-          cmCTestLog(
-            this->CTest, HANDLER_OUTPUT,
-            "\t" << this->CTest->GetColorCode(testColor) << std::setw(3)
-                 << ft.TestCount << " - " << ft.Name << " ("
-                 << this->GetTestStatus(ft) << ")"
-                 << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
-                 << std::endl);
+    for (cmCTestTestResult const& ft : resultsSet) {
+      if (ft.Status != cmCTestTestHandler::COMPLETED &&
+          !cmHasLiteralPrefix(ft.CompletionStatus, "SKIP_") &&
+          ft.CompletionStatus != "Disabled") {
+        ofs << ft.TestCount << ":" << ft.Name << std::endl;
+        auto testColor = cmCTest::Color::RED;
+        if (this->GetTestStatus(ft) == "Not Run") {
+          testColor = cmCTest::Color::YELLOW;
         }
+        cmCTestLog(
+          this->CTest, HANDLER_OUTPUT,
+          "\t" << this->CTest->GetColorCode(testColor) << std::setw(3)
+               << ft.TestCount << " - " << ft.Name << " ("
+               << this->GetTestStatus(ft) << ")"
+               << this->CTest->GetColorCode(cmCTest::Color::CLEAR_COLOR)
+               << std::endl);
       }
     }
   }
+}
 
+bool cmCTestTestHandler::GenerateXML()
+{
   if (this->CTest->GetProduceXML()) {
     cmGeneratedFileStream xmlfile;
     if (!this->StartResultingXML(
@@ -627,23 +669,13 @@
                    << (this->MemCheck ? "memory check" : "testing")
                    << " XML file" << std::endl);
       this->LogFile = nullptr;
-      return 1;
+      return false;
     }
     cmXMLWriter xml(xmlfile);
     this->GenerateDartOutput(xml);
   }
 
-  if (!this->PostProcessHandler()) {
-    this->LogFile = nullptr;
-    return -1;
-  }
-
-  if (!failed.empty()) {
-    this->LogFile = nullptr;
-    return -1;
-  }
-  this->LogFile = nullptr;
-  return 0;
+  return true;
 }
 
 void cmCTestTestHandler::PrintLabelOrSubprojectSummary(bool doSubProject)
@@ -1682,36 +1714,34 @@
   cm.GetCurrentSnapshot().SetDefaultDefinitions();
   cmGlobalGenerator gg(&cm);
   cmMakefile mf(&gg, cm.GetCurrentSnapshot());
-  mf.AddDefinition("CTEST_CONFIGURATION_TYPE",
-                   this->CTest->GetConfigType().c_str());
+  mf.AddDefinition("CTEST_CONFIGURATION_TYPE", this->CTest->GetConfigType());
 
   // Add handler for ADD_TEST
-  cmCTestAddTestCommand* newCom1 = new cmCTestAddTestCommand;
+  auto newCom1 = cm::make_unique<cmCTestAddTestCommand>();
   newCom1->TestHandler = this;
-  cm.GetState()->AddBuiltinCommand("add_test", newCom1);
+  cm.GetState()->AddBuiltinCommand("add_test", std::move(newCom1));
 
   // Add handler for SUBDIRS
-  cmCTestSubdirCommand* newCom2 = new cmCTestSubdirCommand;
+  auto newCom2 = cm::make_unique<cmCTestSubdirCommand>();
   newCom2->TestHandler = this;
-  cm.GetState()->AddBuiltinCommand("subdirs", newCom2);
+  cm.GetState()->AddBuiltinCommand("subdirs", std::move(newCom2));
 
   // Add handler for ADD_SUBDIRECTORY
-  cmCTestAddSubdirectoryCommand* newCom3 = new cmCTestAddSubdirectoryCommand;
+  auto newCom3 = cm::make_unique<cmCTestAddSubdirectoryCommand>();
   newCom3->TestHandler = this;
-  cm.GetState()->AddBuiltinCommand("add_subdirectory", newCom3);
+  cm.GetState()->AddBuiltinCommand("add_subdirectory", std::move(newCom3));
 
   // Add handler for SET_TESTS_PROPERTIES
-  cmCTestSetTestsPropertiesCommand* newCom4 =
-    new cmCTestSetTestsPropertiesCommand;
+  auto newCom4 = cm::make_unique<cmCTestSetTestsPropertiesCommand>();
   newCom4->TestHandler = this;
-  cm.GetState()->AddBuiltinCommand("set_tests_properties", newCom4);
+  cm.GetState()->AddBuiltinCommand("set_tests_properties", std::move(newCom4));
 
   // Add handler for SET_DIRECTORY_PROPERTIES
   cm.GetState()->RemoveBuiltinCommand("set_directory_properties");
-  cmCTestSetDirectoryPropertiesCommand* newCom5 =
-    new cmCTestSetDirectoryPropertiesCommand;
+  auto newCom5 = cm::make_unique<cmCTestSetDirectoryPropertiesCommand>();
   newCom5->TestHandler = this;
-  cm.GetState()->AddBuiltinCommand("set_directory_properties", newCom5);
+  cm.GetState()->AddBuiltinCommand("set_directory_properties",
+                                   std::move(newCom5));
 
   const char* testFilename;
   if (cmSystemTools::FileExists("CTestTestfile.cmake")) {
@@ -2229,6 +2259,13 @@
               rt.ErrorRegularExpressions.emplace_back(cr, cr);
             }
           }
+          if (key == "SKIP_REGULAR_EXPRESSION") {
+            std::vector<std::string> lval;
+            cmSystemTools::ExpandListArgument(val, lval);
+            for (std::string const& cr : lval) {
+              rt.SkipRegularExpressions.emplace_back(cr, cr);
+            }
+          }
           if (key == "PROCESSORS") {
             rt.Processors = atoi(val.c_str());
             if (rt.Processors < 1) {
diff --git a/Source/CTest/cmCTestTestHandler.h b/Source/CTest/cmCTestTestHandler.h
index 7f3f5e4..9345185 100644
--- a/Source/CTest/cmCTestTestHandler.h
+++ b/Source/CTest/cmCTestTestHandler.h
@@ -118,6 +118,8 @@
     std::vector<std::pair<cmsys::RegularExpression, std::string>>
       RequiredRegularExpressions;
     std::vector<std::pair<cmsys::RegularExpression, std::string>>
+      SkipRegularExpressions;
+    std::vector<std::pair<cmsys::RegularExpression, std::string>>
       TimeoutRegularExpressions;
     std::map<std::string, std::string> Measurements;
     bool IsInBasedOnREOptions;
@@ -189,12 +191,25 @@
   typedef std::vector<cmCTestTestProperties> ListOfTests;
 
 protected:
+  typedef std::set<cmCTestTestHandler::cmCTestTestResult,
+                   cmCTestTestResultLess>
+    SetOfTests;
+
   // compute a final test list
   virtual int PreProcessHandler();
   virtual int PostProcessHandler();
   virtual void GenerateTestCommand(std::vector<std::string>& args, int test);
   int ExecuteCommands(std::vector<std::string>& vec);
 
+  bool ProcessOptions();
+  void LogTestSummary(const std::vector<std::string>& passed,
+                      const std::vector<std::string>& failed,
+                      const cmDuration& durationInSecs);
+  void LogDisabledTests(const std::vector<cmCTestTestResult>& disabledTests);
+  void LogFailedTests(const std::vector<std::string>& failed,
+                      const SetOfTests& resultsSet);
+  bool GenerateXML();
+
   void WriteTestResultHeader(cmXMLWriter& xml,
                              cmCTestTestResult const& result);
   void WriteTestResultFooter(cmXMLWriter& xml,
diff --git a/Source/CTest/cmCTestUpdateCommand.h b/Source/CTest/cmCTestUpdateCommand.h
index 3b2f3e1..55c4b80 100644
--- a/Source/CTest/cmCTestUpdateCommand.h
+++ b/Source/CTest/cmCTestUpdateCommand.h
@@ -6,11 +6,14 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include "cmCTestHandlerCommand.h"
+#include "cmCommand.h"
 
 #include <string>
+#include <utility>
+
+#include "cm_memory.hxx"
 
 class cmCTestGenericHandler;
-class cmCommand;
 
 /** \class cmCTestUpdate
  * \brief Run a ctest script
@@ -25,12 +28,12 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestUpdateCommand* ni = new cmCTestUpdateCommand;
+    auto ni = cm::make_unique<cmCTestUpdateCommand>();
     ni->CTest = this->CTest;
     ni->CTestScriptHandler = this->CTestScriptHandler;
-    return ni;
+    return std::unique_ptr<cmCommand>(std::move(ni));
   }
 
   /**
diff --git a/Source/CTest/cmCTestUpdateHandler.cxx b/Source/CTest/cmCTestUpdateHandler.cxx
index fb97e9b..d80b5a5 100644
--- a/Source/CTest/cmCTestUpdateHandler.cxx
+++ b/Source/CTest/cmCTestUpdateHandler.cxx
@@ -2,7 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmCTestUpdateHandler.h"
 
-#include "cmAlgorithms.h"
 #include "cmCLocaleEnvironmentScope.h"
 #include "cmCTest.h"
 #include "cmCTestBZR.h"
@@ -18,9 +17,10 @@
 #include "cmXMLWriter.h"
 
 #include <chrono>
-#include <memory>
 #include <sstream>
 
+#include "cm_memory.hxx"
+
 static const char* cmCTestUpdateHandlerUpdateStrings[] = {
   "Unknown", "CVS", "SVN", "BZR", "GIT", "HG", "P4"
 };
diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h
index 0d3b06e..2bb072f 100644
--- a/Source/CTest/cmCTestUploadCommand.h
+++ b/Source/CTest/cmCTestUploadCommand.h
@@ -6,12 +6,15 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include "cmCTestHandlerCommand.h"
+#include "cmCommand.h"
 
 #include <set>
 #include <string>
+#include <utility>
+
+#include "cm_memory.hxx"
 
 class cmCTestGenericHandler;
-class cmCommand;
 
 /** \class cmCTestUpload
  * \brief Run a ctest script
@@ -25,12 +28,12 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmCTestUploadCommand* ni = new cmCTestUploadCommand;
+    auto ni = cm::make_unique<cmCTestUploadCommand>();
     ni->CTest = this->CTest;
     ni->CTestScriptHandler = this->CTestScriptHandler;
-    return ni;
+    return std::unique_ptr<cmCommand>(std::move(ni));
   }
 
   /**
diff --git a/Source/LexerParser/cmCommandArgumentParser.cxx b/Source/LexerParser/cmCommandArgumentParser.cxx
index b965b32..ae7fb42 100644
--- a/Source/LexerParser/cmCommandArgumentParser.cxx
+++ b/Source/LexerParser/cmCommandArgumentParser.cxx
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
+/* A Bison parser, made by GNU Bison 3.3.2.  */
 
 /* Bison implementation for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -40,11 +41,14 @@
    define necessary library symbols; they are noted "INFRINGES ON
    USER NAME SPACE" below.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 /* Identify Bison output.  */
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "3.0.4"
+#define YYBISON_VERSION "3.3.2"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -67,8 +71,8 @@
 #define yynerrs         cmCommandArgument_yynerrs
 
 
-/* Copy the first part of user declarations.  */
-#line 1 "cmCommandArgumentParser.y" /* yacc.c:339  */
+/* First part of user prologue.  */
+#line 1 "cmCommandArgumentParser.y" /* yacc.c:337  */
 
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
@@ -130,13 +134,16 @@
 # pragma GCC diagnostic ignored "-Wconversion"
 #endif
 
-#line 134 "cmCommandArgumentParser.cxx" /* yacc.c:339  */
-
+#line 138 "cmCommandArgumentParser.cxx" /* yacc.c:337  */
 # ifndef YY_NULLPTR
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULLPTR nullptr
+#  if defined __cplusplus
+#   if 201103L <= __cplusplus
+#    define YY_NULLPTR nullptr
+#   else
+#    define YY_NULLPTR 0
+#   endif
 #  else
-#   define YY_NULLPTR 0
+#   define YY_NULLPTR ((void*)0)
 #  endif
 # endif
 
@@ -201,9 +208,7 @@
 
 #endif /* !YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED  */
 
-/* Copy the second part of user declarations.  */
 
-#line 207 "cmCommandArgumentParser.cxx" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -224,13 +229,13 @@
 #ifdef YYTYPE_UINT16
 typedef YYTYPE_UINT16 yytype_uint16;
 #else
-typedef unsigned short int yytype_uint16;
+typedef unsigned short yytype_uint16;
 #endif
 
 #ifdef YYTYPE_INT16
 typedef YYTYPE_INT16 yytype_int16;
 #else
-typedef short int yytype_int16;
+typedef short yytype_int16;
 #endif
 
 #ifndef YYSIZE_T
@@ -242,7 +247,7 @@
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
-#  define YYSIZE_T unsigned int
+#  define YYSIZE_T unsigned
 # endif
 #endif
 
@@ -278,15 +283,6 @@
 # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
 #endif
 
-#if !defined _Noreturn \
-     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-#  define _Noreturn __declspec (noreturn)
-# else
-#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
 # define YYUSE(E) ((void) (E))
@@ -294,7 +290,7 @@
 # define YYUSE(E) /* empty */
 #endif
 
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
 /* Suppress an incorrect diagnostic about yylval being uninitialized.  */
 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
     _Pragma ("GCC diagnostic push") \
@@ -456,16 +452,16 @@
 /* YYNSTATES -- Number of states.  */
 #define YYNSTATES  33
 
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
-   by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   269
 
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, with out-of-bounds checking.  */
 #define YYTRANSLATE(YYX)                                                \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+  ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex, without out-of-bounds checking.  */
+   as returned by yylex.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -513,7 +509,7 @@
 static const char *const yytname[] =
 {
   "$end", "error", "$undefined", "cal_ENVCURLY", "cal_NCURLY",
-  "cal_DCURLY", "\"$\"", "\"{\"", "\"}\"", "cal_NAME", R"("\\")",
+  "cal_DCURLY", "\"$\"", "\"{\"", "\"}\"", "cal_NAME", "\"\\\\\"",
   "cal_SYMBOL", "\"@\"", "cal_ERROR", "cal_ATNAME", "$accept", "Start",
   "GoalWithOptionalBackSlash", "Goal", "String", "OuterText", "Variable",
   "EnvVarName", "MultipleIds", "ID", YY_NULLPTR
@@ -633,22 +629,22 @@
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
-      yyerror (yyscanner, YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (0)
+#define YYBACKUP(Token, Value)                                    \
+  do                                                              \
+    if (yychar == YYEMPTY)                                        \
+      {                                                           \
+        yychar = (Token);                                         \
+        yylval = (Value);                                         \
+        YYPOPSTACK (yylen);                                       \
+        yystate = *yyssp;                                         \
+        goto yybackup;                                            \
+      }                                                           \
+    else                                                          \
+      {                                                           \
+        yyerror (yyscanner, YY_("syntax error: cannot back up")); \
+        YYERROR;                                                  \
+      }                                                           \
+  while (0)
 
 /* Error token number */
 #define YYTERROR        1
@@ -688,38 +684,38 @@
 } while (0)
 
 
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT.  |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO.  |
+`-----------------------------------*/
 
 static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
 {
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
+  FILE *yyoutput = yyo;
+  YYUSE (yyoutput);
   YYUSE (yyscanner);
   if (!yyvaluep)
     return;
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+    YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
 # endif
   YYUSE (yytype);
 }
 
 
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO.  |
+`---------------------------*/
 
 static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
 {
-  YYFPRINTF (yyoutput, "%s %s (",
+  YYFPRINTF (yyo, "%s %s (",
              yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
 
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner);
-  YYFPRINTF (yyoutput, ")");
+  yy_symbol_value_print (yyo, yytype, yyvaluep, yyscanner);
+  YYFPRINTF (yyo, ")");
 }
 
 /*------------------------------------------------------------------.
@@ -753,7 +749,7 @@
 static void
 yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner)
 {
-  unsigned long int yylno = yyrline[yyrule];
+  unsigned long yylno = yyrline[yyrule];
   int yynrhs = yyr2[yyrule];
   int yyi;
   YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
@@ -764,7 +760,7 @@
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr,
                        yystos[yyssp[yyi + 1 - yynrhs]],
-                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                       &yyvsp[(yyi + 1) - (yynrhs)]
                                               , yyscanner);
       YYFPRINTF (stderr, "\n");
     }
@@ -868,7 +864,10 @@
           case '\\':
             if (*++yyp != '\\')
               goto do_not_strip_quotes;
-            /* Fall through.  */
+            else
+              goto append;
+
+          append:
           default:
             if (yyres)
               yyres[yyn] = *yyp;
@@ -886,7 +885,7 @@
   if (! yyres)
     return yystrlen (yystr);
 
-  return yystpcpy (yyres, yystr) - yyres;
+  return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
 }
 # endif
 
@@ -964,10 +963,10 @@
                 yyarg[yycount++] = yytname[yyx];
                 {
                   YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+                    yysize = yysize1;
+                  else
                     return 2;
-                  yysize = yysize1;
                 }
               }
         }
@@ -979,6 +978,7 @@
       case N:                               \
         yyformat = S;                       \
       break
+    default: /* Avoid compiler warnings. */
       YYCASE_(0, YY_("syntax error"));
       YYCASE_(1, YY_("syntax error, unexpected %s"));
       YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -990,9 +990,10 @@
 
   {
     YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+      yysize = yysize1;
+    else
       return 2;
-    yysize = yysize1;
   }
 
   if (*yymsg_alloc < yysize)
@@ -1123,23 +1124,31 @@
   yychar = YYEMPTY; /* Cause a token to be read.  */
   goto yysetstate;
 
+
 /*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
+| yynewstate -- push a new state, which is found in yystate.  |
 `------------------------------------------------------------*/
- yynewstate:
+yynewstate:
   /* In all cases, when you get here, the value and location stacks
      have just been pushed.  So pushing a state here evens the stacks.  */
   yyssp++;
 
- yysetstate:
-  *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate.  |
+`--------------------------------------------------------------------*/
+yysetstate:
+  *yyssp = (yytype_int16) yystate;
 
   if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+    goto yyexhaustedlab;
+#else
     {
       /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
+      YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
 
-#ifdef yyoverflow
+# if defined yyoverflow
       {
         /* Give user a chance to reallocate the stack.  Use copies of
            these so that the &'s don't force the real ones into
@@ -1155,14 +1164,10 @@
                     &yyss1, yysize * sizeof (*yyssp),
                     &yyvs1, yysize * sizeof (*yyvsp),
                     &yystacksize);
-
         yyss = yyss1;
         yyvs = yyvs1;
       }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
         goto yyexhaustedlab;
@@ -1178,22 +1183,22 @@
           goto yyexhaustedlab;
         YYSTACK_RELOCATE (yyss_alloc, yyss);
         YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-#  undef YYSTACK_RELOCATE
+# undef YYSTACK_RELOCATE
         if (yyss1 != yyssa)
           YYSTACK_FREE (yyss1);
       }
 # endif
-#endif /* no yyoverflow */
 
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                  (unsigned long int) yystacksize));
+                  (unsigned long) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
         YYABORT;
     }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
@@ -1202,11 +1207,11 @@
 
   goto yybackup;
 
+
 /*-----------.
 | yybackup.  |
 `-----------*/
 yybackup:
-
   /* Do appropriate processing given the current state.  Read a
      lookahead token if we need one and don't already have one.  */
 
@@ -1279,7 +1284,7 @@
 
 
 /*-----------------------------.
-| yyreduce -- Do a reduction.  |
+| yyreduce -- do a reduction.  |
 `-----------------------------*/
 yyreduce:
   /* yyn is the number of a rule to reduce with.  */
@@ -1300,192 +1305,192 @@
   switch (yyn)
     {
         case 2:
-#line 99 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 99 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = 0;
     yyGetParser->SetResult((yyvsp[0].str));
   }
-#line 1309 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1314 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 3:
-#line 105 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 105 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[0].str);
   }
-#line 1317 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1322 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 4:
-#line 108 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 108 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
   }
-#line 1325 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1330 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 5:
-#line 113 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 113 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = 0;
   }
-#line 1333 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1338 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 6:
-#line 116 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 116 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
   }
-#line 1341 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1346 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 7:
-#line 121 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 121 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[0].str);
   }
-#line 1349 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1354 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 8:
-#line 124 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 124 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[0].str);
   }
-#line 1357 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1362 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 9:
-#line 129 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 129 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[0].str);
   }
-#line 1365 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1370 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 10:
-#line 132 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 132 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[0].str);
   }
-#line 1373 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1378 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 11:
-#line 135 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 135 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[0].str);
   }
-#line 1381 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1386 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 12:
-#line 138 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 138 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[0].str);
   }
-#line 1389 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1394 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 13:
-#line 141 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 141 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[0].str);
   }
-#line 1397 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1402 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 14:
-#line 144 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 144 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[0].str);
   }
-#line 1405 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1410 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 15:
-#line 149 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 149 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
   }
-#line 1413 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1418 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 16:
-#line 152 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 152 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = yyGetParser->ExpandSpecialVariable((yyvsp[-2].str), (yyvsp[-1].str));
   }
-#line 1421 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1426 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 17:
-#line 155 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 155 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = yyGetParser->ExpandVariable((yyvsp[-1].str));
   }
-#line 1429 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1434 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 18:
-#line 158 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 158 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = yyGetParser->ExpandVariableForAt((yyvsp[0].str));
   }
-#line 1437 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1442 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 19:
-#line 163 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 163 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[0].str);
   }
-#line 1445 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1450 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 20:
-#line 166 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 166 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[-1].str);
   }
-#line 1453 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1458 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 21:
-#line 171 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 171 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = 0;
   }
-#line 1461 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1466 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 22:
-#line 174 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 174 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = yyGetParser->CombineUnions((yyvsp[-1].str), (yyvsp[0].str));
   }
-#line 1469 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1474 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 23:
-#line 179 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 179 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[0].str);
   }
-#line 1477 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1482 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
   case 24:
-#line 182 "cmCommandArgumentParser.y" /* yacc.c:1646  */
+#line 182 "cmCommandArgumentParser.y" /* yacc.c:1652  */
     {
     (yyval.str) = (yyvsp[0].str);
   }
-#line 1485 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1490 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
     break;
 
 
-#line 1489 "cmCommandArgumentParser.cxx" /* yacc.c:1646  */
+#line 1494 "cmCommandArgumentParser.cxx" /* yacc.c:1652  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1510,14 +1515,13 @@
   /* Now 'shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
+  {
+    const int yylhs = yyr1[yyn] - YYNTOKENS;
+    const int yyi = yypgoto[yylhs] + *yyssp;
+    yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+               ? yytable[yyi]
+               : yydefgoto[yylhs]);
+  }
 
   goto yynewstate;
 
@@ -1601,12 +1605,10 @@
 | yyerrorlab -- error raised explicitly by YYERROR.  |
 `---------------------------------------------------*/
 yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
+  /* Pacify compilers when the user code never invokes YYERROR and the
+     label yyerrorlab therefore never appears in user code.  */
+  if (0)
+    YYERROR;
 
   /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
@@ -1669,6 +1671,7 @@
   yyresult = 0;
   goto yyreturn;
 
+
 /*-----------------------------------.
 | yyabortlab -- YYABORT comes here.  |
 `-----------------------------------*/
@@ -1676,6 +1679,7 @@
   yyresult = 1;
   goto yyreturn;
 
+
 #if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
@@ -1686,6 +1690,10 @@
   /* Fall through.  */
 #endif
 
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result.  |
+`-----------------------------------------------------*/
 yyreturn:
   if (yychar != YYEMPTY)
     {
@@ -1715,7 +1723,7 @@
 #endif
   return yyresult;
 }
-#line 187 "cmCommandArgumentParser.y" /* yacc.c:1906  */
+#line 187 "cmCommandArgumentParser.y" /* yacc.c:1918  */
 
 /* End of grammar */
 
diff --git a/Source/LexerParser/cmCommandArgumentParserTokens.h b/Source/LexerParser/cmCommandArgumentParserTokens.h
index 3172182..56c9794 100644
--- a/Source/LexerParser/cmCommandArgumentParserTokens.h
+++ b/Source/LexerParser/cmCommandArgumentParserTokens.h
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
+/* A Bison parser, made by GNU Bison 3.3.2.  */
 
 /* Bison interface for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -30,6 +31,9 @@
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 #ifndef YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED
 # define YY_CMCOMMANDARGUMENT_YY_CMCOMMANDARGUMENTPARSERTOKENS_H_INCLUDED
 /* Debug traces.  */
diff --git a/Source/LexerParser/cmDependsJavaParser.cxx b/Source/LexerParser/cmDependsJavaParser.cxx
index e83afa9..6c1fb2c 100644
--- a/Source/LexerParser/cmDependsJavaParser.cxx
+++ b/Source/LexerParser/cmDependsJavaParser.cxx
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
+/* A Bison parser, made by GNU Bison 3.3.2.  */
 
 /* Bison implementation for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -40,11 +41,14 @@
    define necessary library symbols; they are noted "INFRINGES ON
    USER NAME SPACE" below.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 /* Identify Bison output.  */
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "3.0.4"
+#define YYBISON_VERSION "3.3.2"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -67,8 +71,8 @@
 #define yynerrs         cmDependsJava_yynerrs
 
 
-/* Copy the first part of user declarations.  */
-#line 1 "cmDependsJavaParser.y" /* yacc.c:339  */
+/* First part of user prologue.  */
+#line 1 "cmDependsJavaParser.y" /* yacc.c:337  */
 
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
@@ -119,13 +123,16 @@
 # pragma GCC diagnostic ignored "-Wconversion"
 #endif
 
-#line 123 "cmDependsJavaParser.cxx" /* yacc.c:339  */
-
+#line 127 "cmDependsJavaParser.cxx" /* yacc.c:337  */
 # ifndef YY_NULLPTR
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULLPTR nullptr
+#  if defined __cplusplus
+#   if 201103L <= __cplusplus
+#    define YY_NULLPTR nullptr
+#   else
+#    define YY_NULLPTR 0
+#   endif
 #  else
-#   define YY_NULLPTR 0
+#   define YY_NULLPTR ((void*)0)
 #  endif
 # endif
 
@@ -372,9 +379,7 @@
 
 #endif /* !YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED  */
 
-/* Copy the second part of user declarations.  */
 
-#line 378 "cmDependsJavaParser.cxx" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -395,13 +400,13 @@
 #ifdef YYTYPE_UINT16
 typedef YYTYPE_UINT16 yytype_uint16;
 #else
-typedef unsigned short int yytype_uint16;
+typedef unsigned short yytype_uint16;
 #endif
 
 #ifdef YYTYPE_INT16
 typedef YYTYPE_INT16 yytype_int16;
 #else
-typedef short int yytype_int16;
+typedef short yytype_int16;
 #endif
 
 #ifndef YYSIZE_T
@@ -413,7 +418,7 @@
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
-#  define YYSIZE_T unsigned int
+#  define YYSIZE_T unsigned
 # endif
 #endif
 
@@ -449,15 +454,6 @@
 # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
 #endif
 
-#if !defined _Noreturn \
-     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-#  define _Noreturn __declspec (noreturn)
-# else
-#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
 # define YYUSE(E) ((void) (E))
@@ -465,7 +461,7 @@
 # define YYUSE(E) /* empty */
 #endif
 
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
 /* Suppress an incorrect diagnostic about yylval being uninitialized.  */
 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
     _Pragma ("GCC diagnostic push") \
@@ -627,16 +623,16 @@
 /* YYNSTATES -- Number of states.  */
 #define YYNSTATES  575
 
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
-   by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   360
 
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, with out-of-bounds checking.  */
 #define YYTRANSLATE(YYX)                                                \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+  ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex, without out-of-bounds checking.  */
+   as returned by yylex.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -1618,22 +1614,22 @@
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
-      yyerror (yyscanner, YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (0)
+#define YYBACKUP(Token, Value)                                    \
+  do                                                              \
+    if (yychar == YYEMPTY)                                        \
+      {                                                           \
+        yychar = (Token);                                         \
+        yylval = (Value);                                         \
+        YYPOPSTACK (yylen);                                       \
+        yystate = *yyssp;                                         \
+        goto yybackup;                                            \
+      }                                                           \
+    else                                                          \
+      {                                                           \
+        yyerror (yyscanner, YY_("syntax error: cannot back up")); \
+        YYERROR;                                                  \
+      }                                                           \
+  while (0)
 
 /* Error token number */
 #define YYTERROR        1
@@ -1673,38 +1669,38 @@
 } while (0)
 
 
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT.  |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO.  |
+`-----------------------------------*/
 
 static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
 {
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
+  FILE *yyoutput = yyo;
+  YYUSE (yyoutput);
   YYUSE (yyscanner);
   if (!yyvaluep)
     return;
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+    YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
 # endif
   YYUSE (yytype);
 }
 
 
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO.  |
+`---------------------------*/
 
 static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
 {
-  YYFPRINTF (yyoutput, "%s %s (",
+  YYFPRINTF (yyo, "%s %s (",
              yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
 
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner);
-  YYFPRINTF (yyoutput, ")");
+  yy_symbol_value_print (yyo, yytype, yyvaluep, yyscanner);
+  YYFPRINTF (yyo, ")");
 }
 
 /*------------------------------------------------------------------.
@@ -1738,7 +1734,7 @@
 static void
 yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner)
 {
-  unsigned long int yylno = yyrline[yyrule];
+  unsigned long yylno = yyrline[yyrule];
   int yynrhs = yyr2[yyrule];
   int yyi;
   YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
@@ -1749,7 +1745,7 @@
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr,
                        yystos[yyssp[yyi + 1 - yynrhs]],
-                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                       &yyvsp[(yyi + 1) - (yynrhs)]
                                               , yyscanner);
       YYFPRINTF (stderr, "\n");
     }
@@ -1853,7 +1849,10 @@
           case '\\':
             if (*++yyp != '\\')
               goto do_not_strip_quotes;
-            /* Fall through.  */
+            else
+              goto append;
+
+          append:
           default:
             if (yyres)
               yyres[yyn] = *yyp;
@@ -1871,7 +1870,7 @@
   if (! yyres)
     return yystrlen (yystr);
 
-  return yystpcpy (yyres, yystr) - yyres;
+  return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
 }
 # endif
 
@@ -1949,10 +1948,10 @@
                 yyarg[yycount++] = yytname[yyx];
                 {
                   YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+                    yysize = yysize1;
+                  else
                     return 2;
-                  yysize = yysize1;
                 }
               }
         }
@@ -1964,6 +1963,7 @@
       case N:                               \
         yyformat = S;                       \
       break
+    default: /* Avoid compiler warnings. */
       YYCASE_(0, YY_("syntax error"));
       YYCASE_(1, YY_("syntax error, unexpected %s"));
       YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -1975,9 +1975,10 @@
 
   {
     YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+      yysize = yysize1;
+    else
       return 2;
-    yysize = yysize1;
   }
 
   if (*yymsg_alloc < yysize)
@@ -2108,23 +2109,31 @@
   yychar = YYEMPTY; /* Cause a token to be read.  */
   goto yysetstate;
 
+
 /*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
+| yynewstate -- push a new state, which is found in yystate.  |
 `------------------------------------------------------------*/
- yynewstate:
+yynewstate:
   /* In all cases, when you get here, the value and location stacks
      have just been pushed.  So pushing a state here evens the stacks.  */
   yyssp++;
 
- yysetstate:
-  *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate.  |
+`--------------------------------------------------------------------*/
+yysetstate:
+  *yyssp = (yytype_int16) yystate;
 
   if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+    goto yyexhaustedlab;
+#else
     {
       /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
+      YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
 
-#ifdef yyoverflow
+# if defined yyoverflow
       {
         /* Give user a chance to reallocate the stack.  Use copies of
            these so that the &'s don't force the real ones into
@@ -2140,14 +2149,10 @@
                     &yyss1, yysize * sizeof (*yyssp),
                     &yyvs1, yysize * sizeof (*yyvsp),
                     &yystacksize);
-
         yyss = yyss1;
         yyvs = yyvs1;
       }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
         goto yyexhaustedlab;
@@ -2163,22 +2168,22 @@
           goto yyexhaustedlab;
         YYSTACK_RELOCATE (yyss_alloc, yyss);
         YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-#  undef YYSTACK_RELOCATE
+# undef YYSTACK_RELOCATE
         if (yyss1 != yyssa)
           YYSTACK_FREE (yyss1);
       }
 # endif
-#endif /* no yyoverflow */
 
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                  (unsigned long int) yystacksize));
+                  (unsigned long) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
         YYABORT;
     }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
@@ -2187,11 +2192,11 @@
 
   goto yybackup;
 
+
 /*-----------.
 | yybackup.  |
 `-----------*/
 yybackup:
-
   /* Do appropriate processing given the current state.  Read a
      lookahead token if we need one and don't already have one.  */
 
@@ -2264,7 +2269,7 @@
 
 
 /*-----------------------------.
-| yyreduce -- Do a reduction.  |
+| yyreduce -- do a reduction.  |
 `-----------------------------*/
 yyreduce:
   /* yyn is the number of a rule to reduce with.  */
@@ -2285,214 +2290,214 @@
   switch (yyn)
     {
         case 2:
-#line 183 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 183 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2296 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2301 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 3:
-#line 192 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 192 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2307 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2312 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 4:
-#line 200 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 200 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2318 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2323 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 5:
-#line 208 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 208 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2329 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2334 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 6:
-#line 216 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 216 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2340 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2345 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 7:
-#line 224 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 224 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2351 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2356 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 8:
-#line 232 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 232 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2362 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2367 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 9:
-#line 241 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 241 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2373 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2378 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 10:
-#line 249 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 249 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2384 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2389 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 11:
-#line 258 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 258 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2395 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2400 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 12:
-#line 266 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 266 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2406 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2411 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 13:
-#line 275 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 275 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
 }
-#line 2414 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2419 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 14:
-#line 280 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 280 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
 }
-#line 2422 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2427 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 15:
-#line 285 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 285 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
 }
-#line 2430 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2435 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 16:
-#line 290 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 290 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
 }
-#line 2438 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2443 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 17:
-#line 295 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 295 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
 }
-#line 2446 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2451 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 18:
-#line 300 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 300 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
 }
-#line 2454 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2459 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 19:
-#line 305 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 305 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
 }
-#line 2462 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2467 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 20:
-#line 310 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 310 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
 }
-#line 2470 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2475 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 21:
-#line 316 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 316 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2481 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2486 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 22:
-#line 324 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 324 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2492 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2497 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 23:
-#line 333 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 333 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpStoreClass((yyvsp[0].str));
@@ -2500,44 +2505,44 @@
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2504 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2509 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 24:
-#line 343 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 343 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2515 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2520 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 25:
-#line 352 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 352 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2526 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2531 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 26:
-#line 361 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 361 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2537 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2542 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 27:
-#line 369 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 369 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpStoreClass((yyvsp[-1].str));
@@ -2545,56 +2550,56 @@
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2549 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2554 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 28:
-#line 379 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 379 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   (yyval.str) = (yyvsp[0].str);
 }
-#line 2558 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2563 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 29:
-#line 385 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 385 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   (yyval.str) = (yyvsp[0].str);
 }
-#line 2567 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2572 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 30:
-#line 392 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 392 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   (yyval.str) = (yyvsp[0].str);
 }
-#line 2576 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2581 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 31:
-#line 399 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 399 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   (yyval.str) = (yyvsp[0].str);
 }
-#line 2585 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2590 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 32:
-#line 405 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 405 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   (yyval.str) = (yyvsp[0].str);
 }
-#line 2594 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2599 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 33:
-#line 412 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 412 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   yyGetParser->AddClassFound((yyvsp[-2].str));
@@ -2602,11 +2607,11 @@
   yyGetParser->DeallocateParserType(&((yyvsp[-2].str)));
   (yyval.str) = const_cast<char*>(yyGetParser->GetCurrentCombine());
 }
-#line 2606 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2611 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 34:
-#line 421 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 421 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpStoreClass((yyvsp[-2].str));
@@ -2615,11 +2620,11 @@
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2619 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2624 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 35:
-#line 431 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 431 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpStoreClass((yyvsp[-2].str));
@@ -2628,118 +2633,118 @@
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2632 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2637 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 36:
-#line 441 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 441 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2643 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2648 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 37:
-#line 450 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 450 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2654 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2659 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 38:
-#line 458 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 458 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2665 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2670 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 39:
-#line 467 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 467 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2676 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2681 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 40:
-#line 475 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 475 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2686 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2691 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 41:
-#line 482 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 482 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2697 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2702 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 42:
-#line 490 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 490 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2707 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2712 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 43:
-#line 497 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 497 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2718 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2723 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 44:
-#line 505 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 505 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2728 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2733 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 45:
-#line 512 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 512 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2739 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2744 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 46:
-#line 521 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 521 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   yyGetParser->SetCurrentPackage((yyvsp[-1].str));
@@ -2749,33 +2754,33 @@
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2753 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2758 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 47:
-#line 533 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 533 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2764 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2769 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 48:
-#line 541 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 541 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2775 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2780 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 49:
-#line 550 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 550 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   yyGetParser->AddPackagesImport((yyvsp[-1].str));
@@ -2785,11 +2790,11 @@
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2789 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2794 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 50:
-#line 562 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 562 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
   std::string str = (yyvsp[-3].str);
@@ -2800,77 +2805,77 @@
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2804 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2809 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 51:
-#line 575 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 575 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2815 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2820 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 52:
-#line 583 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 583 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2826 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2831 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 53:
-#line 591 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 591 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2837 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2842 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 54:
-#line 600 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 600 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2848 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2853 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 55:
-#line 608 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 608 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2859 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2864 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 67:
-#line 623 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 623 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   yyGetParser->StartClass((yyvsp[0].str));
   jpElementStart(3);
   yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
   jpCheckEmpty(3);
 }
-#line 2870 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2875 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 68:
-#line 633 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 633 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -2878,11 +2883,11 @@
   yyGetParser->SetCurrentCombine("");
   yyGetParser->EndClass();
 }
-#line 2882 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2887 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 69:
-#line 642 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 642 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(2);
@@ -2890,11 +2895,11 @@
   yyGetParser->SetCurrentCombine("");
   yyGetParser->EndClass();
 }
-#line 2894 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2899 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 70:
-#line 651 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 651 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -2902,11 +2907,11 @@
   yyGetParser->SetCurrentCombine("");
   yyGetParser->EndClass();
 }
-#line 2906 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2911 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 71:
-#line 660 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 660 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   jpCheckEmpty(4);
@@ -2914,226 +2919,226 @@
   yyGetParser->SetCurrentCombine("");
   yyGetParser->EndClass();
 }
-#line 2918 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2923 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 72:
-#line 669 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 669 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2928 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2933 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 73:
-#line 676 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 676 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2939 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2944 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 74:
-#line 685 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 685 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2950 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2955 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 75:
-#line 694 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 694 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2961 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2966 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 76:
-#line 703 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 703 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2972 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2977 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 77:
-#line 711 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 711 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2983 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2988 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 78:
-#line 720 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 720 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 2994 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 2999 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 79:
-#line 728 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 728 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3004 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3009 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 80:
-#line 735 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 735 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3015 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3020 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 81:
-#line 744 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 744 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3026 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3031 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 82:
-#line 752 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 752 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3037 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3042 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 83:
-#line 760 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 760 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3048 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3053 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 84:
-#line 768 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 768 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3059 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3064 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 85:
-#line 777 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 777 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3070 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3075 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 86:
-#line 785 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 785 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3081 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3086 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 87:
-#line 794 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 794 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
 }
-#line 3089 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3094 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 88:
-#line 800 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 800 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3100 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3105 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 89:
-#line 808 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 808 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3111 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3116 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 90:
-#line 817 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 817 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3122 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3127 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 91:
-#line 825 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 825 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3133 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3138 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 92:
-#line 834 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 834 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -3141,77 +3146,77 @@
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3145 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3150 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 93:
-#line 843 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 843 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3156 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3161 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 94:
-#line 852 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 852 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3167 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3172 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 95:
-#line 860 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 860 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3178 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3183 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 96:
-#line 869 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 869 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3189 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3194 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 97:
-#line 877 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 877 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3200 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3205 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 98:
-#line 885 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 885 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3211 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3216 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 99:
-#line 894 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 894 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   jpCheckEmpty(4);
@@ -3219,11 +3224,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3223 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3228 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 100:
-#line 903 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 903 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   jpCheckEmpty(4);
@@ -3231,22 +3236,22 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3235 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3240 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 101:
-#line 912 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 912 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3246 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3251 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 102:
-#line 920 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 920 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3254,11 +3259,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3258 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3263 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 103:
-#line 930 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 930 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -3267,40 +3272,40 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3271 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3276 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 104:
-#line 940 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 940 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
 
 }
-#line 3280 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3285 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 105:
-#line 946 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 946 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3291 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3296 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 107:
-#line 957 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 957 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
 
 }
-#line 3300 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3305 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 108:
-#line 963 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 963 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -3308,11 +3313,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3312 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3317 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 109:
-#line 973 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 973 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -3320,11 +3325,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3324 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3329 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 110:
-#line 983 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 983 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -3332,20 +3337,20 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3336 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3341 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 111:
-#line 993 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 993 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
 
 }
-#line 3345 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3350 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 112:
-#line 999 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 999 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -3353,11 +3358,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3357 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3362 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 113:
-#line 1009 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1009 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3365,11 +3370,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3369 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3374 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 114:
-#line 1019 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1019 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -3377,11 +3382,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3381 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3386 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 115:
-#line 1029 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1029 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   jpCheckEmpty(4);
@@ -3389,11 +3394,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3393 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3398 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 116:
-#line 1038 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1038 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
   jpCheckEmpty(5);
@@ -3401,11 +3406,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3405 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3410 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 117:
-#line 1048 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1048 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -3414,11 +3419,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3418 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3423 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 118:
-#line 1059 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1059 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   jpCheckEmpty(4);
@@ -3426,22 +3431,22 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3430 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3435 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 119:
-#line 1068 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1068 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3441 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3446 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 120:
-#line 1076 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1076 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -3449,11 +3454,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3453 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3458 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 121:
-#line 1086 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1086 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
   jpCheckEmpty(5);
@@ -3461,11 +3466,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3465 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3470 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 122:
-#line 1095 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1095 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
   jpCheckEmpty(5);
@@ -3473,22 +3478,22 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3477 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3482 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 123:
-#line 1105 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1105 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   yyGetParser->StartClass((yyvsp[0].str));
   jpElementStart(3);
   yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
   jpCheckEmpty(3);
 }
-#line 3488 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3493 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 124:
-#line 1114 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1114 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -3496,21 +3501,21 @@
   yyGetParser->SetCurrentCombine("");
   yyGetParser->EndClass();
 }
-#line 3500 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3505 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 125:
-#line 1123 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1123 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 }
-#line 3510 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3515 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 126:
-#line 1130 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1130 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3518,11 +3523,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3522 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3527 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 127:
-#line 1140 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1140 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -3530,11 +3535,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3534 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3539 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 128:
-#line 1149 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1149 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -3542,11 +3547,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3546 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3551 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 129:
-#line 1159 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1159 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -3554,33 +3559,33 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3558 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3563 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 130:
-#line 1168 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1168 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3569 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3574 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 131:
-#line 1176 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1176 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3580 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3585 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 132:
-#line 1185 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1185 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3588,11 +3593,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3592 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3597 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 133:
-#line 1194 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1194 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3600,11 +3605,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3604 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3609 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 134:
-#line 1203 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1203 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3612,22 +3617,22 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3616 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3621 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 135:
-#line 1212 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1212 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3627 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3632 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 136:
-#line 1220 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1220 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3635,22 +3640,22 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3639 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3644 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 137:
-#line 1229 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1229 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3650 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3655 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 138:
-#line 1238 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1238 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3658,11 +3663,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3662 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3667 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 139:
-#line 1248 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1248 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -3670,11 +3675,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3674 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3679 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 140:
-#line 1258 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1258 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3682,11 +3687,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3686 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3691 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 141:
-#line 1267 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1267 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -3694,11 +3699,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3698 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3703 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 142:
-#line 1277 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1277 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -3706,22 +3711,22 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3710 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3715 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 143:
-#line 1286 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1286 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3721 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3726 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 144:
-#line 1294 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1294 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3729,11 +3734,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3733 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3738 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 145:
-#line 1303 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1303 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -3741,11 +3746,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3745 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3750 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 146:
-#line 1313 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1313 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3753,11 +3758,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3757 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3762 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 147:
-#line 1322 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1322 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -3765,33 +3770,33 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3769 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3774 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 148:
-#line 1332 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1332 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3780 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3785 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 149:
-#line 1340 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1340 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3791 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3796 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 150:
-#line 1348 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1348 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3799,11 +3804,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3803 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3808 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 151:
-#line 1358 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1358 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3811,11 +3816,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3815 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3820 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 152:
-#line 1367 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1367 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(2);
@@ -3823,11 +3828,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3827 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3832 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 153:
-#line 1377 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1377 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3835,11 +3840,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3839 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3844 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 154:
-#line 1386 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1386 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3847,11 +3852,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3851 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3856 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 155:
-#line 1395 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1395 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3859,11 +3864,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3863 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3868 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 156:
-#line 1405 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1405 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(2);
@@ -3871,11 +3876,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3875 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3880 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 157:
-#line 1415 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1415 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(3);
@@ -3883,11 +3888,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3887 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3892 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 158:
-#line 1424 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1424 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(2);
@@ -3895,11 +3900,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3899 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3904 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 159:
-#line 1434 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1434 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3907,11 +3912,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3911 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3916 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 160:
-#line 1443 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1443 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3919,11 +3924,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3923 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3928 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 161:
-#line 1452 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1452 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3931,11 +3936,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3935 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3940 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 162:
-#line 1461 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1461 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3943,11 +3948,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3947 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3952 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 163:
-#line 1470 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1470 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3955,11 +3960,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3959 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3964 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 164:
-#line 1479 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1479 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3967,11 +3972,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3971 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3976 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 165:
-#line 1489 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1489 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3979,11 +3984,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3983 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 3988 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 166:
-#line 1498 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1498 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -3991,11 +3996,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 3995 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4000 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 167:
-#line 1507 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1507 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4003,11 +4008,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4007 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4012 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 168:
-#line 1516 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1516 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4015,11 +4020,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4019 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4024 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 169:
-#line 1525 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1525 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4027,11 +4032,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4031 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4036 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 170:
-#line 1535 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1535 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4039,11 +4044,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4043 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4048 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 171:
-#line 1544 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1544 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4051,11 +4056,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4055 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4060 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 172:
-#line 1553 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1553 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4063,11 +4068,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4067 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4072 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 173:
-#line 1562 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1562 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4075,11 +4080,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4079 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4084 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 174:
-#line 1571 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1571 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4087,11 +4092,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4091 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4096 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 175:
-#line 1580 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1580 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4099,11 +4104,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4103 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4108 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 176:
-#line 1589 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1589 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4111,11 +4116,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4115 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4120 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 177:
-#line 1598 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1598 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4123,11 +4128,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4127 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4132 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 178:
-#line 1607 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1607 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4135,11 +4140,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4139 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4144 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 179:
-#line 1616 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1616 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4147,11 +4152,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4151 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4156 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 180:
-#line 1625 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1625 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4159,11 +4164,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4163 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4168 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 181:
-#line 1634 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1634 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4171,11 +4176,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4175 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4180 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 182:
-#line 1644 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1644 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4183,11 +4188,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4187 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4192 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 183:
-#line 1654 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1654 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   yyGetParser->DeallocateParserType(&((yyvsp[-2].str)));
@@ -4196,11 +4201,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4200 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4205 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 184:
-#line 1665 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1665 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -4208,11 +4213,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4212 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4217 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 185:
-#line 1675 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1675 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -4220,11 +4225,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4224 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4229 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 186:
-#line 1685 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1685 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4232,11 +4237,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4236 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4241 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 187:
-#line 1694 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1694 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4244,11 +4249,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4248 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4253 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 188:
-#line 1703 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1703 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4256,11 +4261,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4260 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4265 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 189:
-#line 1712 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1712 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4268,11 +4273,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4272 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4277 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 190:
-#line 1721 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1721 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4280,11 +4285,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4284 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4289 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 191:
-#line 1730 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1730 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4292,11 +4297,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4296 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4301 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 192:
-#line 1739 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1739 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4304,11 +4309,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4308 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4313 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 193:
-#line 1749 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1749 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
   jpCheckEmpty(5);
@@ -4316,11 +4321,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4320 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4325 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 194:
-#line 1759 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1759 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(7);
   jpCheckEmpty(7);
@@ -4328,11 +4333,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4332 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4337 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 195:
-#line 1769 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1769 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(7);
   jpCheckEmpty(7);
@@ -4340,40 +4345,40 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4344 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4349 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 196:
-#line 1779 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1779 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
 
 }
-#line 4353 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4358 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 197:
-#line 1786 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1786 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
 
 }
-#line 4362 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4367 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 198:
-#line 1792 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1792 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4373 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4378 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 199:
-#line 1800 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1800 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4381,22 +4386,22 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4385 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4390 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 200:
-#line 1809 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1809 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4396 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4401 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 201:
-#line 1817 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1817 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -4404,11 +4409,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4408 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4413 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 202:
-#line 1827 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1827 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -4416,11 +4421,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4420 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4425 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 203:
-#line 1837 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1837 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4428,11 +4433,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4432 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4437 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 204:
-#line 1846 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1846 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -4440,11 +4445,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4444 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4449 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 205:
-#line 1856 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1856 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -4452,11 +4457,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4456 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4461 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 206:
-#line 1865 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1865 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -4464,58 +4469,58 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4468 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4473 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 207:
-#line 1875 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1875 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
 
 }
-#line 4477 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4482 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 208:
-#line 1882 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1882 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
 
 }
-#line 4486 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4491 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 209:
-#line 1889 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1889 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(7);
 
 }
-#line 4495 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4500 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 210:
-#line 1897 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1897 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(9);
 
 }
-#line 4504 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4509 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 211:
-#line 1903 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1903 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4515 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4520 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 212:
-#line 1911 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1911 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4523,22 +4528,22 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4527 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4532 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 213:
-#line 1920 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1920 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4538 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4543 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 214:
-#line 1928 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1928 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4546,33 +4551,33 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4550 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4555 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 215:
-#line 1939 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1939 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(9);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4561 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4566 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 216:
-#line 1947 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1947 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4572 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4577 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 217:
-#line 1955 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1955 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4580,11 +4585,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4584 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4589 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 218:
-#line 1965 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1965 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4592,11 +4597,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4596 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4601 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 219:
-#line 1974 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1974 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4604,11 +4609,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4608 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4613 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 220:
-#line 1984 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1984 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4616,11 +4621,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4620 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4625 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 221:
-#line 1994 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 1994 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4628,11 +4633,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4632 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4637 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 222:
-#line 2003 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2003 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -4640,11 +4645,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4644 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4649 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 223:
-#line 2013 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2013 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -4652,11 +4657,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4656 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4661 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 224:
-#line 2022 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2022 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
   jpCheckEmpty(5);
@@ -4664,11 +4669,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4668 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4673 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 225:
-#line 2032 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2032 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   yyGetParser->DeallocateParserType(&((yyvsp[-1].str)));
@@ -4677,31 +4682,31 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4681 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4686 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 226:
-#line 2042 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2042 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4692 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4697 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 227:
-#line 2050 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2050 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
 
 }
-#line 4701 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4706 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 228:
-#line 2057 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2057 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   yyGetParser->DeallocateParserType(&((yyvsp[-1].str)));
@@ -4710,11 +4715,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4714 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4719 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 229:
-#line 2068 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2068 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -4722,11 +4727,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4726 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4731 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 230:
-#line 2078 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2078 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -4734,11 +4739,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4738 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4743 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 231:
-#line 2088 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2088 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
   jpCheckEmpty(5);
@@ -4746,11 +4751,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4750 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4755 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 232:
-#line 2098 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2098 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -4758,11 +4763,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4762 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4767 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 233:
-#line 2107 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2107 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   jpCheckEmpty(4);
@@ -4770,22 +4775,22 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4774 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4779 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 234:
-#line 2116 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2116 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4785 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4790 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 235:
-#line 2124 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2124 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4793,11 +4798,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4797 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4802 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 236:
-#line 2134 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2134 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4805,11 +4810,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4809 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4814 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 237:
-#line 2143 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2143 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -4817,20 +4822,20 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4821 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4826 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 238:
-#line 2153 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2153 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
 
 }
-#line 4830 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4835 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 239:
-#line 2160 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2160 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -4838,11 +4843,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4842 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4847 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 240:
-#line 2170 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2170 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4850,11 +4855,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4854 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4859 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 241:
-#line 2179 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2179 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4862,11 +4867,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4866 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4871 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 242:
-#line 2189 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2189 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4874,20 +4879,20 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4878 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4883 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 243:
-#line 2198 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2198 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
 
 }
-#line 4887 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4892 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 244:
-#line 2204 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2204 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -4895,11 +4900,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4899 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4904 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 245:
-#line 2213 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2213 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4907,11 +4912,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4911 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4916 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 246:
-#line 2222 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2222 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4919,11 +4924,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4923 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4928 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 247:
-#line 2231 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2231 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4931,11 +4936,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4935 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4940 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 248:
-#line 2240 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2240 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4943,11 +4948,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4947 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4952 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 249:
-#line 2250 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2250 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(6);
   jpCheckEmpty(6);
@@ -4955,22 +4960,22 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4959 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4964 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 250:
-#line 2259 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2259 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4970 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4975 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 251:
-#line 2267 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2267 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -4978,22 +4983,22 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4982 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4987 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 252:
-#line 2276 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2276 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 4993 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 4998 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 253:
-#line 2284 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2284 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5001,11 +5006,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5005 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5010 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 254:
-#line 2294 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2294 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5013,11 +5018,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5017 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5022 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 255:
-#line 2303 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2303 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5025,11 +5030,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5029 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5034 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 256:
-#line 2313 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2313 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   jpCheckEmpty(4);
@@ -5037,11 +5042,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5041 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5046 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 257:
-#line 2322 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2322 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   jpCheckEmpty(4);
@@ -5049,11 +5054,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5053 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5058 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 258:
-#line 2331 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2331 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   jpCheckEmpty(4);
@@ -5061,11 +5066,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5065 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5070 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 259:
-#line 2340 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2340 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   jpCheckEmpty(4);
@@ -5073,22 +5078,22 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5077 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5082 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 260:
-#line 2349 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2349 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(0);
   (yyval.str) = 0;
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5088 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5093 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 261:
-#line 2357 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2357 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5096,11 +5101,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5100 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5105 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 262:
-#line 2367 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2367 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5108,11 +5113,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5112 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5117 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 263:
-#line 2376 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2376 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -5120,11 +5125,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5124 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5129 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 264:
-#line 2386 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2386 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5132,29 +5137,29 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5136 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5141 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 265:
-#line 2396 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2396 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
 
 }
-#line 5145 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5150 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 266:
-#line 2402 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2402 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
 
 }
-#line 5154 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5159 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 267:
-#line 2409 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2409 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5163,11 +5168,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5167 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5172 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 268:
-#line 2419 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2419 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5176,11 +5181,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5180 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5185 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 269:
-#line 2429 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2429 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5189,11 +5194,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5193 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5198 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 270:
-#line 2439 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2439 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5202,11 +5207,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5206 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5211 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 271:
-#line 2450 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2450 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5215,11 +5220,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5219 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5224 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 272:
-#line 2460 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2460 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(6);
   yyGetParser->DeallocateParserType(&((yyvsp[-5].str)));
@@ -5229,11 +5234,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5233 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5238 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 273:
-#line 2471 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2471 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(6);
   yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5242,11 +5247,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5246 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5251 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 274:
-#line 2481 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2481 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(6);
   yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5255,11 +5260,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5259 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5264 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 275:
-#line 2492 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2492 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   yyGetParser->DeallocateParserType(&((yyvsp[-3].str)));
@@ -5268,11 +5273,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5272 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5277 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 276:
-#line 2502 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2502 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   jpCheckEmpty(4);
@@ -5280,11 +5285,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5284 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5289 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 277:
-#line 2512 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2512 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5292,11 +5297,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5296 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5301 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 278:
-#line 2521 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2521 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5304,11 +5309,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5308 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5313 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 279:
-#line 2530 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2530 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5316,11 +5321,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5320 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5325 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 280:
-#line 2539 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2539 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5328,11 +5333,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5332 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5337 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 281:
-#line 2548 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2548 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5340,11 +5345,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5344 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5349 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 282:
-#line 2558 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2558 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -5352,11 +5357,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5356 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5361 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 283:
-#line 2568 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2568 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -5364,11 +5369,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5368 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5373 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 284:
-#line 2578 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2578 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5376,11 +5381,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5380 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5385 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 285:
-#line 2587 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2587 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5388,11 +5393,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5392 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5397 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 286:
-#line 2596 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2596 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -5400,11 +5405,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5404 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5409 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 287:
-#line 2605 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2605 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -5412,11 +5417,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5416 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5421 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 288:
-#line 2614 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2614 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5424,11 +5429,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5428 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5433 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 289:
-#line 2624 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2624 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -5436,11 +5441,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5440 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5445 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 290:
-#line 2634 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2634 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -5448,11 +5453,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5452 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5457 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 291:
-#line 2644 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2644 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5460,11 +5465,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5464 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5469 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 292:
-#line 2653 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2653 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -5472,11 +5477,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5476 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5481 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 293:
-#line 2662 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2662 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(2);
   jpCheckEmpty(2);
@@ -5484,11 +5489,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5488 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5493 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 294:
-#line 2671 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2671 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5496,11 +5501,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5500 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5505 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 295:
-#line 2681 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2681 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
   jpCheckEmpty(5);
@@ -5508,11 +5513,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5512 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5517 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 296:
-#line 2690 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2690 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(4);
   jpCheckEmpty(4);
@@ -5520,20 +5525,20 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5524 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5529 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 297:
-#line 2699 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2699 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
 
 }
-#line 5533 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5538 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 298:
-#line 2706 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2706 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5541,11 +5546,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5545 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5550 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 299:
-#line 2715 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2715 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5553,11 +5558,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5557 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5562 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 300:
-#line 2724 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2724 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5565,11 +5570,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5569 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5574 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 301:
-#line 2733 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2733 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5577,11 +5582,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5581 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5586 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 302:
-#line 2743 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2743 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5589,11 +5594,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5593 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5598 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 303:
-#line 2752 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2752 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5601,11 +5606,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5605 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5610 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 304:
-#line 2761 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2761 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5613,11 +5618,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5617 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5622 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 305:
-#line 2771 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2771 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5625,11 +5630,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5629 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5634 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 306:
-#line 2780 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2780 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5637,11 +5642,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5641 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5646 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 307:
-#line 2789 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2789 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5649,11 +5654,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5653 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5658 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 308:
-#line 2798 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2798 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5661,11 +5666,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5665 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5670 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 309:
-#line 2808 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2808 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5673,11 +5678,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5677 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5682 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 310:
-#line 2817 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2817 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5685,11 +5690,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5689 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5694 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 311:
-#line 2826 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2826 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5697,11 +5702,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5701 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5706 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 312:
-#line 2835 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2835 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5709,11 +5714,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5713 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5718 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 313:
-#line 2844 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2844 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5721,11 +5726,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5725 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5730 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 314:
-#line 2853 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2853 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5733,11 +5738,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5737 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5742 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 315:
-#line 2863 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2863 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5745,11 +5750,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5749 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5754 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 316:
-#line 2872 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2872 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5757,11 +5762,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5761 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5766 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 317:
-#line 2881 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2881 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5769,11 +5774,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5773 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5778 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 318:
-#line 2891 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2891 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5781,11 +5786,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5785 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5790 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 319:
-#line 2900 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2900 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5793,11 +5798,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5797 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5802 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 320:
-#line 2910 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2910 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5805,11 +5810,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5809 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5814 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 321:
-#line 2919 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2919 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5817,11 +5822,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5821 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5826 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 322:
-#line 2929 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2929 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5829,11 +5834,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5833 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5838 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 323:
-#line 2938 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2938 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5841,11 +5846,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5845 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5850 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 324:
-#line 2948 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2948 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5853,11 +5858,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5857 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5862 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 325:
-#line 2957 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2957 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5865,11 +5870,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5869 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5874 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 326:
-#line 2967 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2967 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5877,11 +5882,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5881 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5886 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 327:
-#line 2976 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2976 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5889,11 +5894,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5893 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5898 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 328:
-#line 2986 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2986 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5901,11 +5906,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5905 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5910 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 329:
-#line 2995 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 2995 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(5);
   jpCheckEmpty(5);
@@ -5913,11 +5918,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5917 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5922 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 330:
-#line 3005 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3005 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5925,11 +5930,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5929 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5934 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 331:
-#line 3014 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3014 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5937,11 +5942,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5941 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5946 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 332:
-#line 3024 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3024 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpCheckEmpty(3);
@@ -5949,11 +5954,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5953 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5958 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 333:
-#line 3034 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3034 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   yyGetParser->DeallocateParserType(&((yyvsp[0].str)));
@@ -5962,11 +5967,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5966 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5971 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 334:
-#line 3044 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3044 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5974,11 +5979,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5978 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5983 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 335:
-#line 3053 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3053 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5986,11 +5991,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 5990 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 5995 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 336:
-#line 3063 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3063 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -5998,11 +6003,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6002 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6007 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 337:
-#line 3072 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3072 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6010,11 +6015,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6014 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6019 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 338:
-#line 3081 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3081 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6022,11 +6027,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6026 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6031 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 339:
-#line 3090 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3090 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6034,11 +6039,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6038 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6043 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 340:
-#line 3099 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3099 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6046,11 +6051,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6050 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6055 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 341:
-#line 3108 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3108 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6058,11 +6063,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6062 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6067 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 342:
-#line 3117 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3117 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6070,11 +6075,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6074 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6079 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 343:
-#line 3126 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3126 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6082,11 +6087,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6086 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6091 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 344:
-#line 3135 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3135 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6094,11 +6099,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6098 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6103 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 345:
-#line 3144 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3144 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6106,11 +6111,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6110 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6115 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 346:
-#line 3153 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3153 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6118,11 +6123,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6122 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6127 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 347:
-#line 3162 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3162 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6130,11 +6135,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6134 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6139 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 348:
-#line 3172 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3172 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6142,11 +6147,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6146 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6151 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 349:
-#line 3182 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3182 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6154,11 +6159,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6158 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6163 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 350:
-#line 3192 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3192 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(1);
   jpCheckEmpty(1);
@@ -6166,11 +6171,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6170 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6175 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
   case 351:
-#line 3201 "cmDependsJavaParser.y" /* yacc.c:1646  */
+#line 3201 "cmDependsJavaParser.y" /* yacc.c:1652  */
     {
   jpElementStart(3);
   jpStoreClass((yyvsp[-2].str));
@@ -6179,11 +6184,11 @@
   yyGetParser->SetCurrentCombine("");
 
 }
-#line 6183 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6188 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
     break;
 
 
-#line 6187 "cmDependsJavaParser.cxx" /* yacc.c:1646  */
+#line 6192 "cmDependsJavaParser.cxx" /* yacc.c:1652  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -6208,14 +6213,13 @@
   /* Now 'shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
+  {
+    const int yylhs = yyr1[yyn] - YYNTOKENS;
+    const int yyi = yypgoto[yylhs] + *yyssp;
+    yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+               ? yytable[yyi]
+               : yydefgoto[yylhs]);
+  }
 
   goto yynewstate;
 
@@ -6299,12 +6303,10 @@
 | yyerrorlab -- error raised explicitly by YYERROR.  |
 `---------------------------------------------------*/
 yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
+  /* Pacify compilers when the user code never invokes YYERROR and the
+     label yyerrorlab therefore never appears in user code.  */
+  if (0)
+    YYERROR;
 
   /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
@@ -6367,6 +6369,7 @@
   yyresult = 0;
   goto yyreturn;
 
+
 /*-----------------------------------.
 | yyabortlab -- YYABORT comes here.  |
 `-----------------------------------*/
@@ -6374,6 +6377,7 @@
   yyresult = 1;
   goto yyreturn;
 
+
 #if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
@@ -6384,6 +6388,10 @@
   /* Fall through.  */
 #endif
 
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result.  |
+`-----------------------------------------------------*/
 yyreturn:
   if (yychar != YYEMPTY)
     {
@@ -6413,7 +6421,7 @@
 #endif
   return yyresult;
 }
-#line 3210 "cmDependsJavaParser.y" /* yacc.c:1906  */
+#line 3210 "cmDependsJavaParser.y" /* yacc.c:1918  */
 
 /* End of grammar */
 
diff --git a/Source/LexerParser/cmDependsJavaParserTokens.h b/Source/LexerParser/cmDependsJavaParserTokens.h
index 7f18f1d..6bbc084 100644
--- a/Source/LexerParser/cmDependsJavaParserTokens.h
+++ b/Source/LexerParser/cmDependsJavaParserTokens.h
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
+/* A Bison parser, made by GNU Bison 3.3.2.  */
 
 /* Bison interface for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -30,6 +31,9 @@
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 #ifndef YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED
 # define YY_CMDEPENDSJAVA_YY_CMDEPENDSJAVAPARSERTOKENS_H_INCLUDED
 /* Debug traces.  */
diff --git a/Source/LexerParser/cmExprParser.cxx b/Source/LexerParser/cmExprParser.cxx
index 73ece2b..8416e72 100644
--- a/Source/LexerParser/cmExprParser.cxx
+++ b/Source/LexerParser/cmExprParser.cxx
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
+/* A Bison parser, made by GNU Bison 3.3.2.  */
 
 /* Bison implementation for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -40,11 +41,14 @@
    define necessary library symbols; they are noted "INFRINGES ON
    USER NAME SPACE" below.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 /* Identify Bison output.  */
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "3.0.4"
+#define YYBISON_VERSION "3.3.2"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -67,8 +71,8 @@
 #define yynerrs         cmExpr_yynerrs
 
 
-/* Copy the first part of user declarations.  */
-#line 1 "cmExprParser.y" /* yacc.c:339  */
+/* First part of user prologue.  */
+#line 1 "cmExprParser.y" /* yacc.c:337  */
 
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
@@ -112,13 +116,16 @@
 # pragma GCC diagnostic ignored "-Wconversion"
 #endif
 
-#line 116 "cmExprParser.cxx" /* yacc.c:339  */
-
+#line 120 "cmExprParser.cxx" /* yacc.c:337  */
 # ifndef YY_NULLPTR
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULLPTR nullptr
+#  if defined __cplusplus
+#   if 201103L <= __cplusplus
+#    define YY_NULLPTR nullptr
+#   else
+#    define YY_NULLPTR 0
+#   endif
 #  else
-#   define YY_NULLPTR 0
+#   define YY_NULLPTR ((void*)0)
 #  endif
 # endif
 
@@ -187,9 +194,7 @@
 
 #endif /* !YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED  */
 
-/* Copy the second part of user declarations.  */
 
-#line 193 "cmExprParser.cxx" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -210,13 +215,13 @@
 #ifdef YYTYPE_UINT16
 typedef YYTYPE_UINT16 yytype_uint16;
 #else
-typedef unsigned short int yytype_uint16;
+typedef unsigned short yytype_uint16;
 #endif
 
 #ifdef YYTYPE_INT16
 typedef YYTYPE_INT16 yytype_int16;
 #else
-typedef short int yytype_int16;
+typedef short yytype_int16;
 #endif
 
 #ifndef YYSIZE_T
@@ -228,7 +233,7 @@
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
-#  define YYSIZE_T unsigned int
+#  define YYSIZE_T unsigned
 # endif
 #endif
 
@@ -264,15 +269,6 @@
 # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
 #endif
 
-#if !defined _Noreturn \
-     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-#  define _Noreturn __declspec (noreturn)
-# else
-#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
 # define YYUSE(E) ((void) (E))
@@ -280,7 +276,7 @@
 # define YYUSE(E) /* empty */
 #endif
 
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
 /* Suppress an incorrect diagnostic about yylval being uninitialized.  */
 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
     _Pragma ("GCC diagnostic push") \
@@ -429,29 +425,29 @@
 #endif /* !YYCOPY_NEEDED */
 
 /* YYFINAL -- State number of the termination state.  */
-#define YYFINAL  17
+#define YYFINAL  19
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   30
+#define YYLAST   34
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  17
 /* YYNNTS -- Number of nonterminals.  */
 #define YYNNTS  10
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  23
+#define YYNRULES  24
 /* YYNSTATES -- Number of states.  */
-#define YYNSTATES  39
+#define YYNSTATES  41
 
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
-   by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   271
 
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, with out-of-bounds checking.  */
 #define YYTRANSLATE(YYX)                                                \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+  ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex, without out-of-bounds checking.  */
+   as returned by yylex.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -490,7 +486,7 @@
 {
        0,    77,    77,    82,    85,    90,    93,    98,   101,   106,
      109,   112,   117,   120,   123,   128,   131,   134,   140,   145,
-     148,   151,   156,   159
+     148,   151,   154,   159,   162
 };
 #endif
 
@@ -517,10 +513,10 @@
 };
 # endif
 
-#define YYPACT_NINF -8
+#define YYPACT_NINF -11
 
 #define yypact_value_is_default(Yystate) \
-  (!!((Yystate) == (-8)))
+  (!!((Yystate) == (-11)))
 
 #define YYTABLE_NINF -1
 
@@ -531,10 +527,11 @@
      STATE-NUM.  */
 static const yytype_int8 yypact[] =
 {
-       0,     0,     0,     0,    -8,     2,    -7,    -5,     8,     3,
-      10,     1,    -8,    -8,    -8,    -8,     6,    -8,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    -8,    -5,
-       8,     3,    10,    10,     1,     1,    -8,    -8,    -8
+       1,     1,     1,     1,     1,   -11,     6,   -10,    -4,     9,
+       4,    11,     2,   -11,   -11,   -11,   -11,     7,   -11,   -11,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+     -11,    -4,     9,     4,    11,    11,     2,     2,   -11,   -11,
+     -11
 };
 
   /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -542,22 +539,23 @@
      means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       0,     0,     0,     0,    22,     0,     2,     3,     5,     7,
-       9,    12,    15,    19,    20,    21,     0,     1,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    23,     4,
-       6,     8,    10,    11,    13,    14,    16,    17,    18
+       0,     0,     0,     0,     0,    23,     0,     2,     3,     5,
+       7,     9,    12,    15,    19,    20,    21,     0,    22,     1,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      24,     4,     6,     8,    10,    11,    13,    14,    16,    17,
+      18
 };
 
   /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
-      -8,    -8,    12,     5,    11,     9,    -2,     4,    -1,    -8
+     -11,   -11,    22,    10,     8,    12,    -3,    -2,    -1,   -11
 };
 
   /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int8 yydefgoto[] =
 {
-      -1,     5,     6,     7,     8,     9,    10,    11,    12,    13
+      -1,     6,     7,     8,     9,    10,    11,    12,    13,    14
 };
 
   /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
@@ -565,28 +563,29 @@
      number is the opposite.  If YYTABLE_NINF, syntax error.  */
 static const yytype_uint8 yytable[] =
 {
-      14,    15,    17,     1,     2,    18,    25,    26,    27,    19,
-       3,    21,    22,    23,    24,    16,     4,    28,    18,    32,
-      33,    20,     0,    29,    36,    37,    38,    34,    35,    31,
-      30
+      15,    16,    20,    18,     1,     2,    19,    27,    28,    29,
+      21,     3,    23,    24,    25,    26,     4,     5,    30,    20,
+      34,    35,    22,    36,    37,    17,    38,    39,    40,    32,
+      31,     0,     0,     0,    33
 };
 
 static const yytype_int8 yycheck[] =
 {
-       1,     2,     0,     3,     4,    12,     5,     6,     7,    14,
-      10,     8,     9,     3,     4,     3,    16,    11,    12,    21,
-      22,    13,    -1,    18,    25,    26,    27,    23,    24,    20,
-      19
+       1,     2,    12,     4,     3,     4,     0,     5,     6,     7,
+      14,    10,     8,     9,     3,     4,    15,    16,    11,    12,
+      23,    24,    13,    25,    26,     3,    27,    28,    29,    21,
+      20,    -1,    -1,    -1,    22
 };
 
   /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
      symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,     3,     4,    10,    16,    18,    19,    20,    21,    22,
-      23,    24,    25,    26,    25,    25,    19,     0,    12,    14,
-      13,     8,     9,     3,     4,     5,     6,     7,    11,    20,
-      21,    22,    23,    23,    24,    24,    25,    25,    25
+       0,     3,     4,    10,    15,    16,    18,    19,    20,    21,
+      22,    23,    24,    25,    26,    25,    25,    19,    25,     0,
+      12,    14,    13,     8,     9,     3,     4,     5,     6,     7,
+      11,    20,    21,    22,    23,    23,    24,    24,    25,    25,
+      25
 };
 
   /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
@@ -594,7 +593,7 @@
 {
        0,    17,    18,    19,    19,    20,    20,    21,    21,    22,
       22,    22,    23,    23,    23,    24,    24,    24,    24,    25,
-      25,    25,    26,    26
+      25,    25,    25,    26,    26
 };
 
   /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN.  */
@@ -602,7 +601,7 @@
 {
        0,     2,     1,     1,     3,     1,     3,     1,     3,     1,
        3,     3,     1,     3,     3,     1,     3,     3,     3,     1,
-       2,     2,     1,     3
+       2,     2,     2,     1,     3
 };
 
 
@@ -618,22 +617,22 @@
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
-      yyerror (yyscanner, YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (0)
+#define YYBACKUP(Token, Value)                                    \
+  do                                                              \
+    if (yychar == YYEMPTY)                                        \
+      {                                                           \
+        yychar = (Token);                                         \
+        yylval = (Value);                                         \
+        YYPOPSTACK (yylen);                                       \
+        yystate = *yyssp;                                         \
+        goto yybackup;                                            \
+      }                                                           \
+    else                                                          \
+      {                                                           \
+        yyerror (yyscanner, YY_("syntax error: cannot back up")); \
+        YYERROR;                                                  \
+      }                                                           \
+  while (0)
 
 /* Error token number */
 #define YYTERROR        1
@@ -673,38 +672,38 @@
 } while (0)
 
 
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT.  |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO.  |
+`-----------------------------------*/
 
 static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
 {
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
+  FILE *yyoutput = yyo;
+  YYUSE (yyoutput);
   YYUSE (yyscanner);
   if (!yyvaluep)
     return;
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+    YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
 # endif
   YYUSE (yytype);
 }
 
 
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO.  |
+`---------------------------*/
 
 static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
 {
-  YYFPRINTF (yyoutput, "%s %s (",
+  YYFPRINTF (yyo, "%s %s (",
              yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
 
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner);
-  YYFPRINTF (yyoutput, ")");
+  yy_symbol_value_print (yyo, yytype, yyvaluep, yyscanner);
+  YYFPRINTF (yyo, ")");
 }
 
 /*------------------------------------------------------------------.
@@ -738,7 +737,7 @@
 static void
 yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner)
 {
-  unsigned long int yylno = yyrline[yyrule];
+  unsigned long yylno = yyrline[yyrule];
   int yynrhs = yyr2[yyrule];
   int yyi;
   YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
@@ -749,7 +748,7 @@
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr,
                        yystos[yyssp[yyi + 1 - yynrhs]],
-                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                       &yyvsp[(yyi + 1) - (yynrhs)]
                                               , yyscanner);
       YYFPRINTF (stderr, "\n");
     }
@@ -853,7 +852,10 @@
           case '\\':
             if (*++yyp != '\\')
               goto do_not_strip_quotes;
-            /* Fall through.  */
+            else
+              goto append;
+
+          append:
           default:
             if (yyres)
               yyres[yyn] = *yyp;
@@ -871,7 +873,7 @@
   if (! yyres)
     return yystrlen (yystr);
 
-  return yystpcpy (yyres, yystr) - yyres;
+  return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
 }
 # endif
 
@@ -949,10 +951,10 @@
                 yyarg[yycount++] = yytname[yyx];
                 {
                   YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+                    yysize = yysize1;
+                  else
                     return 2;
-                  yysize = yysize1;
                 }
               }
         }
@@ -964,6 +966,7 @@
       case N:                               \
         yyformat = S;                       \
       break
+    default: /* Avoid compiler warnings. */
       YYCASE_(0, YY_("syntax error"));
       YYCASE_(1, YY_("syntax error, unexpected %s"));
       YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -975,9 +978,10 @@
 
   {
     YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+      yysize = yysize1;
+    else
       return 2;
-    yysize = yysize1;
   }
 
   if (*yymsg_alloc < yysize)
@@ -1108,23 +1112,31 @@
   yychar = YYEMPTY; /* Cause a token to be read.  */
   goto yysetstate;
 
+
 /*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
+| yynewstate -- push a new state, which is found in yystate.  |
 `------------------------------------------------------------*/
- yynewstate:
+yynewstate:
   /* In all cases, when you get here, the value and location stacks
      have just been pushed.  So pushing a state here evens the stacks.  */
   yyssp++;
 
- yysetstate:
-  *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate.  |
+`--------------------------------------------------------------------*/
+yysetstate:
+  *yyssp = (yytype_int16) yystate;
 
   if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+    goto yyexhaustedlab;
+#else
     {
       /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
+      YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
 
-#ifdef yyoverflow
+# if defined yyoverflow
       {
         /* Give user a chance to reallocate the stack.  Use copies of
            these so that the &'s don't force the real ones into
@@ -1140,14 +1152,10 @@
                     &yyss1, yysize * sizeof (*yyssp),
                     &yyvs1, yysize * sizeof (*yyvsp),
                     &yystacksize);
-
         yyss = yyss1;
         yyvs = yyvs1;
       }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
         goto yyexhaustedlab;
@@ -1163,22 +1171,22 @@
           goto yyexhaustedlab;
         YYSTACK_RELOCATE (yyss_alloc, yyss);
         YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-#  undef YYSTACK_RELOCATE
+# undef YYSTACK_RELOCATE
         if (yyss1 != yyssa)
           YYSTACK_FREE (yyss1);
       }
 # endif
-#endif /* no yyoverflow */
 
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                  (unsigned long int) yystacksize));
+                  (unsigned long) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
         YYABORT;
     }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
@@ -1187,11 +1195,11 @@
 
   goto yybackup;
 
+
 /*-----------.
 | yybackup.  |
 `-----------*/
 yybackup:
-
   /* Do appropriate processing given the current state.  Read a
      lookahead token if we need one and don't already have one.  */
 
@@ -1264,7 +1272,7 @@
 
 
 /*-----------------------------.
-| yyreduce -- Do a reduction.  |
+| yyreduce -- do a reduction.  |
 `-----------------------------*/
 yyreduce:
   /* yyn is the number of a rule to reduce with.  */
@@ -1285,186 +1293,194 @@
   switch (yyn)
     {
         case 2:
-#line 77 "cmExprParser.y" /* yacc.c:1646  */
+#line 77 "cmExprParser.y" /* yacc.c:1652  */
     {
     cmExpr_yyget_extra(yyscanner)->SetResult((yyvsp[0].Number));
   }
-#line 1293 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1301 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 3:
-#line 82 "cmExprParser.y" /* yacc.c:1646  */
+#line 82 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[0].Number);
   }
-#line 1301 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1309 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 4:
-#line 85 "cmExprParser.y" /* yacc.c:1646  */
+#line 85 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[-2].Number) | (yyvsp[0].Number);
   }
-#line 1309 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1317 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 5:
-#line 90 "cmExprParser.y" /* yacc.c:1646  */
+#line 90 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[0].Number);
   }
-#line 1317 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1325 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 6:
-#line 93 "cmExprParser.y" /* yacc.c:1646  */
+#line 93 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[-2].Number) ^ (yyvsp[0].Number);
   }
-#line 1325 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1333 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 7:
-#line 98 "cmExprParser.y" /* yacc.c:1646  */
+#line 98 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[0].Number);
   }
-#line 1333 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1341 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 8:
-#line 101 "cmExprParser.y" /* yacc.c:1646  */
+#line 101 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[-2].Number) & (yyvsp[0].Number);
   }
-#line 1341 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1349 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 9:
-#line 106 "cmExprParser.y" /* yacc.c:1646  */
+#line 106 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[0].Number);
   }
-#line 1349 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1357 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 10:
-#line 109 "cmExprParser.y" /* yacc.c:1646  */
+#line 109 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[-2].Number) << (yyvsp[0].Number);
   }
-#line 1357 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1365 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 11:
-#line 112 "cmExprParser.y" /* yacc.c:1646  */
+#line 112 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[-2].Number) >> (yyvsp[0].Number);
   }
-#line 1365 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1373 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 12:
-#line 117 "cmExprParser.y" /* yacc.c:1646  */
+#line 117 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[0].Number);
   }
-#line 1373 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1381 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 13:
-#line 120 "cmExprParser.y" /* yacc.c:1646  */
+#line 120 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[-2].Number) + (yyvsp[0].Number);
   }
-#line 1381 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1389 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 14:
-#line 123 "cmExprParser.y" /* yacc.c:1646  */
+#line 123 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[-2].Number) - (yyvsp[0].Number);
   }
-#line 1389 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1397 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 15:
-#line 128 "cmExprParser.y" /* yacc.c:1646  */
+#line 128 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[0].Number);
   }
-#line 1397 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1405 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 16:
-#line 131 "cmExprParser.y" /* yacc.c:1646  */
+#line 131 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[-2].Number) * (yyvsp[0].Number);
   }
-#line 1405 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1413 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 17:
-#line 134 "cmExprParser.y" /* yacc.c:1646  */
+#line 134 "cmExprParser.y" /* yacc.c:1652  */
     {
     if (yyvsp[0].Number == 0) {
       throw std::overflow_error("divide by zero");
     }
     (yyval.Number) = (yyvsp[-2].Number) / (yyvsp[0].Number);
   }
-#line 1416 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1424 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 18:
-#line 140 "cmExprParser.y" /* yacc.c:1646  */
+#line 140 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[-2].Number) % (yyvsp[0].Number);
   }
-#line 1424 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1432 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 19:
-#line 145 "cmExprParser.y" /* yacc.c:1646  */
+#line 145 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[0].Number);
   }
-#line 1432 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1440 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 20:
-#line 148 "cmExprParser.y" /* yacc.c:1646  */
+#line 148 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = + (yyvsp[0].Number);
   }
-#line 1440 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1448 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 21:
-#line 151 "cmExprParser.y" /* yacc.c:1646  */
+#line 151 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = - (yyvsp[0].Number);
   }
-#line 1448 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1456 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 22:
-#line 156 "cmExprParser.y" /* yacc.c:1646  */
+#line 154 "cmExprParser.y" /* yacc.c:1652  */
     {
-    (yyval.Number) = (yyvsp[0].Number);
+    (yyval.Number) = ~ (yyvsp[0].Number);
   }
-#line 1456 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1464 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
   case 23:
-#line 159 "cmExprParser.y" /* yacc.c:1646  */
+#line 159 "cmExprParser.y" /* yacc.c:1652  */
+    {
+    (yyval.Number) = (yyvsp[0].Number);
+  }
+#line 1472 "cmExprParser.cxx" /* yacc.c:1652  */
+    break;
+
+  case 24:
+#line 162 "cmExprParser.y" /* yacc.c:1652  */
     {
     (yyval.Number) = (yyvsp[-1].Number);
   }
-#line 1464 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1480 "cmExprParser.cxx" /* yacc.c:1652  */
     break;
 
 
-#line 1468 "cmExprParser.cxx" /* yacc.c:1646  */
+#line 1484 "cmExprParser.cxx" /* yacc.c:1652  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1489,14 +1505,13 @@
   /* Now 'shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
+  {
+    const int yylhs = yyr1[yyn] - YYNTOKENS;
+    const int yyi = yypgoto[yylhs] + *yyssp;
+    yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+               ? yytable[yyi]
+               : yydefgoto[yylhs]);
+  }
 
   goto yynewstate;
 
@@ -1580,12 +1595,10 @@
 | yyerrorlab -- error raised explicitly by YYERROR.  |
 `---------------------------------------------------*/
 yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
+  /* Pacify compilers when the user code never invokes YYERROR and the
+     label yyerrorlab therefore never appears in user code.  */
+  if (0)
+    YYERROR;
 
   /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
@@ -1648,6 +1661,7 @@
   yyresult = 0;
   goto yyreturn;
 
+
 /*-----------------------------------.
 | yyabortlab -- YYABORT comes here.  |
 `-----------------------------------*/
@@ -1655,6 +1669,7 @@
   yyresult = 1;
   goto yyreturn;
 
+
 #if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
@@ -1665,6 +1680,10 @@
   /* Fall through.  */
 #endif
 
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result.  |
+`-----------------------------------------------------*/
 yyreturn:
   if (yychar != YYEMPTY)
     {
@@ -1694,7 +1713,7 @@
 #endif
   return yyresult;
 }
-#line 164 "cmExprParser.y" /* yacc.c:1906  */
+#line 167 "cmExprParser.y" /* yacc.c:1918  */
 
 /* End of grammar */
 
diff --git a/Source/LexerParser/cmExprParser.y b/Source/LexerParser/cmExprParser.y
index 2137473..7ae2118 100644
--- a/Source/LexerParser/cmExprParser.y
+++ b/Source/LexerParser/cmExprParser.y
@@ -151,6 +151,9 @@
 | exp_MINUS unary {
     $<Number>$ = - $<Number>2;
   }
+| exp_NOT unary {
+    $<Number>$ = ~ $<Number>2;
+  }
 
 factor:
   exp_NUMBER {
diff --git a/Source/LexerParser/cmExprParserTokens.h b/Source/LexerParser/cmExprParserTokens.h
index 84b2bbd..5ffd7c5 100644
--- a/Source/LexerParser/cmExprParserTokens.h
+++ b/Source/LexerParser/cmExprParserTokens.h
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
+/* A Bison parser, made by GNU Bison 3.3.2.  */
 
 /* Bison interface for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -30,6 +31,9 @@
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 #ifndef YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED
 # define YY_CMEXPR_YY_CMEXPRPARSERTOKENS_H_INCLUDED
 /* Debug traces.  */
diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx
index 015cab9..2ca7927 100644
--- a/Source/LexerParser/cmFortranParser.cxx
+++ b/Source/LexerParser/cmFortranParser.cxx
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
+/* A Bison parser, made by GNU Bison 3.3.2.  */
 
 /* Bison implementation for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -40,11 +41,14 @@
    define necessary library symbols; they are noted "INFRINGES ON
    USER NAME SPACE" below.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 /* Identify Bison output.  */
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "3.0.4"
+#define YYBISON_VERSION "3.3.2"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -67,8 +71,8 @@
 #define yynerrs         cmFortran_yynerrs
 
 
-/* Copy the first part of user declarations.  */
-#line 1 "cmFortranParser.y" /* yacc.c:339  */
+/* First part of user prologue.  */
+#line 1 "cmFortranParser.y" /* yacc.c:337  */
 
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
@@ -131,13 +135,16 @@
 # pragma GCC diagnostic ignored "-Wconversion"
 #endif
 
-#line 135 "cmFortranParser.cxx" /* yacc.c:339  */
-
+#line 139 "cmFortranParser.cxx" /* yacc.c:337  */
 # ifndef YY_NULLPTR
-#  if defined __cplusplus && 201103L <= __cplusplus
-#   define YY_NULLPTR nullptr
+#  if defined __cplusplus
+#   if 201103L <= __cplusplus
+#    define YY_NULLPTR nullptr
+#   else
+#    define YY_NULLPTR 0
+#   endif
 #  else
-#   define YY_NULLPTR 0
+#   define YY_NULLPTR ((void*)0)
 #  endif
 # endif
 
@@ -251,11 +258,11 @@
 
 union YYSTYPE
 {
-#line 73 "cmFortranParser.y" /* yacc.c:355  */
+#line 73 "cmFortranParser.y" /* yacc.c:352  */
 
   char* string;
 
-#line 259 "cmFortranParser.cxx" /* yacc.c:355  */
+#line 266 "cmFortranParser.cxx" /* yacc.c:352  */
 };
 
 typedef union YYSTYPE YYSTYPE;
@@ -269,9 +276,7 @@
 
 #endif /* !YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED  */
 
-/* Copy the second part of user declarations.  */
 
-#line 275 "cmFortranParser.cxx" /* yacc.c:358  */
 
 #ifdef short
 # undef short
@@ -292,13 +297,13 @@
 #ifdef YYTYPE_UINT16
 typedef YYTYPE_UINT16 yytype_uint16;
 #else
-typedef unsigned short int yytype_uint16;
+typedef unsigned short yytype_uint16;
 #endif
 
 #ifdef YYTYPE_INT16
 typedef YYTYPE_INT16 yytype_int16;
 #else
-typedef short int yytype_int16;
+typedef short yytype_int16;
 #endif
 
 #ifndef YYSIZE_T
@@ -310,7 +315,7 @@
 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
 #  define YYSIZE_T size_t
 # else
-#  define YYSIZE_T unsigned int
+#  define YYSIZE_T unsigned
 # endif
 #endif
 
@@ -346,15 +351,6 @@
 # define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
 #endif
 
-#if !defined _Noreturn \
-     && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
-# if defined _MSC_VER && 1200 <= _MSC_VER
-#  define _Noreturn __declspec (noreturn)
-# else
-#  define _Noreturn YY_ATTRIBUTE ((__noreturn__))
-# endif
-#endif
-
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
 # define YYUSE(E) ((void) (E))
@@ -362,7 +358,7 @@
 # define YYUSE(E) /* empty */
 #endif
 
-#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
+#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
 /* Suppress an incorrect diagnostic about yylval being uninitialized.  */
 # define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
     _Pragma ("GCC diagnostic push") \
@@ -524,16 +520,16 @@
 /* YYNSTATES -- Number of states.  */
 #define YYNSTATES  126
 
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
-   by yylex, with out-of-bounds checking.  */
 #define YYUNDEFTOK  2
 #define YYMAXUTOK   295
 
+/* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM
+   as returned by yylex, with out-of-bounds checking.  */
 #define YYTRANSLATE(YYX)                                                \
-  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+  ((unsigned) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
 
 /* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
-   as returned by yylex, without out-of-bounds checking.  */
+   as returned by yylex.  */
 static const yytype_uint8 yytranslate[] =
 {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -863,22 +859,22 @@
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
-#define YYBACKUP(Token, Value)                                  \
-do                                                              \
-  if (yychar == YYEMPTY)                                        \
-    {                                                           \
-      yychar = (Token);                                         \
-      yylval = (Value);                                         \
-      YYPOPSTACK (yylen);                                       \
-      yystate = *yyssp;                                         \
-      goto yybackup;                                            \
-    }                                                           \
-  else                                                          \
-    {                                                           \
-      yyerror (yyscanner, YY_("syntax error: cannot back up")); \
-      YYERROR;                                                  \
-    }                                                           \
-while (0)
+#define YYBACKUP(Token, Value)                                    \
+  do                                                              \
+    if (yychar == YYEMPTY)                                        \
+      {                                                           \
+        yychar = (Token);                                         \
+        yylval = (Value);                                         \
+        YYPOPSTACK (yylen);                                       \
+        yystate = *yyssp;                                         \
+        goto yybackup;                                            \
+      }                                                           \
+    else                                                          \
+      {                                                           \
+        yyerror (yyscanner, YY_("syntax error: cannot back up")); \
+        YYERROR;                                                  \
+      }                                                           \
+  while (0)
 
 /* Error token number */
 #define YYTERROR        1
@@ -918,38 +914,38 @@
 } while (0)
 
 
-/*----------------------------------------.
-| Print this symbol's value on YYOUTPUT.  |
-`----------------------------------------*/
+/*-----------------------------------.
+| Print this symbol's value on YYO.  |
+`-----------------------------------*/
 
 static void
-yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_value_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
 {
-  FILE *yyo = yyoutput;
-  YYUSE (yyo);
+  FILE *yyoutput = yyo;
+  YYUSE (yyoutput);
   YYUSE (yyscanner);
   if (!yyvaluep)
     return;
 # ifdef YYPRINT
   if (yytype < YYNTOKENS)
-    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+    YYPRINT (yyo, yytoknum[yytype], *yyvaluep);
 # endif
   YYUSE (yytype);
 }
 
 
-/*--------------------------------.
-| Print this symbol on YYOUTPUT.  |
-`--------------------------------*/
+/*---------------------------.
+| Print this symbol on YYO.  |
+`---------------------------*/
 
 static void
-yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
+yy_symbol_print (FILE *yyo, int yytype, YYSTYPE const * const yyvaluep, yyscan_t yyscanner)
 {
-  YYFPRINTF (yyoutput, "%s %s (",
+  YYFPRINTF (yyo, "%s %s (",
              yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
 
-  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yyscanner);
-  YYFPRINTF (yyoutput, ")");
+  yy_symbol_value_print (yyo, yytype, yyvaluep, yyscanner);
+  YYFPRINTF (yyo, ")");
 }
 
 /*------------------------------------------------------------------.
@@ -983,7 +979,7 @@
 static void
 yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule, yyscan_t yyscanner)
 {
-  unsigned long int yylno = yyrline[yyrule];
+  unsigned long yylno = yyrline[yyrule];
   int yynrhs = yyr2[yyrule];
   int yyi;
   YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
@@ -994,7 +990,7 @@
       YYFPRINTF (stderr, "   $%d = ", yyi + 1);
       yy_symbol_print (stderr,
                        yystos[yyssp[yyi + 1 - yynrhs]],
-                       &(yyvsp[(yyi + 1) - (yynrhs)])
+                       &yyvsp[(yyi + 1) - (yynrhs)]
                                               , yyscanner);
       YYFPRINTF (stderr, "\n");
     }
@@ -1098,7 +1094,10 @@
           case '\\':
             if (*++yyp != '\\')
               goto do_not_strip_quotes;
-            /* Fall through.  */
+            else
+              goto append;
+
+          append:
           default:
             if (yyres)
               yyres[yyn] = *yyp;
@@ -1116,7 +1115,7 @@
   if (! yyres)
     return yystrlen (yystr);
 
-  return yystpcpy (yyres, yystr) - yyres;
+  return (YYSIZE_T) (yystpcpy (yyres, yystr) - yyres);
 }
 # endif
 
@@ -1194,10 +1193,10 @@
                 yyarg[yycount++] = yytname[yyx];
                 {
                   YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
-                  if (! (yysize <= yysize1
-                         && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+                    yysize = yysize1;
+                  else
                     return 2;
-                  yysize = yysize1;
                 }
               }
         }
@@ -1209,6 +1208,7 @@
       case N:                               \
         yyformat = S;                       \
       break
+    default: /* Avoid compiler warnings. */
       YYCASE_(0, YY_("syntax error"));
       YYCASE_(1, YY_("syntax error, unexpected %s"));
       YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
@@ -1220,9 +1220,10 @@
 
   {
     YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
-    if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    if (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)
+      yysize = yysize1;
+    else
       return 2;
-    yysize = yysize1;
   }
 
   if (*yymsg_alloc < yysize)
@@ -1353,23 +1354,31 @@
   yychar = YYEMPTY; /* Cause a token to be read.  */
   goto yysetstate;
 
+
 /*------------------------------------------------------------.
-| yynewstate -- Push a new state, which is found in yystate.  |
+| yynewstate -- push a new state, which is found in yystate.  |
 `------------------------------------------------------------*/
- yynewstate:
+yynewstate:
   /* In all cases, when you get here, the value and location stacks
      have just been pushed.  So pushing a state here evens the stacks.  */
   yyssp++;
 
- yysetstate:
-  *yyssp = yystate;
+
+/*--------------------------------------------------------------------.
+| yynewstate -- set current state (the top of the stack) to yystate.  |
+`--------------------------------------------------------------------*/
+yysetstate:
+  *yyssp = (yytype_int16) yystate;
 
   if (yyss + yystacksize - 1 <= yyssp)
+#if !defined yyoverflow && !defined YYSTACK_RELOCATE
+    goto yyexhaustedlab;
+#else
     {
       /* Get the current used size of the three stacks, in elements.  */
-      YYSIZE_T yysize = yyssp - yyss + 1;
+      YYSIZE_T yysize = (YYSIZE_T) (yyssp - yyss + 1);
 
-#ifdef yyoverflow
+# if defined yyoverflow
       {
         /* Give user a chance to reallocate the stack.  Use copies of
            these so that the &'s don't force the real ones into
@@ -1385,14 +1394,10 @@
                     &yyss1, yysize * sizeof (*yyssp),
                     &yyvs1, yysize * sizeof (*yyvsp),
                     &yystacksize);
-
         yyss = yyss1;
         yyvs = yyvs1;
       }
-#else /* no yyoverflow */
-# ifndef YYSTACK_RELOCATE
-      goto yyexhaustedlab;
-# else
+# else /* defined YYSTACK_RELOCATE */
       /* Extend the stack our own way.  */
       if (YYMAXDEPTH <= yystacksize)
         goto yyexhaustedlab;
@@ -1408,22 +1413,22 @@
           goto yyexhaustedlab;
         YYSTACK_RELOCATE (yyss_alloc, yyss);
         YYSTACK_RELOCATE (yyvs_alloc, yyvs);
-#  undef YYSTACK_RELOCATE
+# undef YYSTACK_RELOCATE
         if (yyss1 != yyssa)
           YYSTACK_FREE (yyss1);
       }
 # endif
-#endif /* no yyoverflow */
 
       yyssp = yyss + yysize - 1;
       yyvsp = yyvs + yysize - 1;
 
       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
-                  (unsigned long int) yystacksize));
+                  (unsigned long) yystacksize));
 
       if (yyss + yystacksize - 1 <= yyssp)
         YYABORT;
     }
+#endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */
 
   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
 
@@ -1432,11 +1437,11 @@
 
   goto yybackup;
 
+
 /*-----------.
 | yybackup.  |
 `-----------*/
 yybackup:
-
   /* Do appropriate processing given the current state.  Read a
      lookahead token if we need one and don't already have one.  */
 
@@ -1509,7 +1514,7 @@
 
 
 /*-----------------------------.
-| yyreduce -- Do a reduction.  |
+| yyreduce -- do a reduction.  |
 `-----------------------------*/
 yyreduce:
   /* yyn is the number of a rule to reduce with.  */
@@ -1530,26 +1535,26 @@
   switch (yyn)
     {
         case 4:
-#line 104 "cmFortranParser.y" /* yacc.c:1646  */
+#line 104 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_SetInInterface(parser, true);
   }
-#line 1539 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1544 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 5:
-#line 108 "cmFortranParser.y" /* yacc.c:1646  */
+#line 108 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1549 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1554 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 6:
-#line 113 "cmFortranParser.y" /* yacc.c:1646  */
+#line 113 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     if (cmsysString_strcasecmp((yyvsp[-2].string), "function") != 0 &&
@@ -1559,22 +1564,22 @@
     }
     free((yyvsp[-2].string));
   }
-#line 1563 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1568 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 7:
-#line 122 "cmFortranParser.y" /* yacc.c:1646  */
+#line 122 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleSubmodule(parser, (yyvsp[-4].string), (yyvsp[-2].string));
     free((yyvsp[-4].string));
     free((yyvsp[-2].string));
   }
-#line 1574 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1579 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 8:
-#line 128 "cmFortranParser.y" /* yacc.c:1646  */
+#line 128 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleSubmoduleNested(parser, (yyvsp[-6].string), (yyvsp[-4].string), (yyvsp[-2].string));
@@ -1582,40 +1587,40 @@
     free((yyvsp[-4].string));
     free((yyvsp[-2].string));
   }
-#line 1586 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1591 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 9:
-#line 135 "cmFortranParser.y" /* yacc.c:1646  */
+#line 135 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_SetInInterface(parser, true);
     free((yyvsp[-2].string));
   }
-#line 1596 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1601 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 10:
-#line 140 "cmFortranParser.y" /* yacc.c:1646  */
+#line 140 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_SetInInterface(parser, false);
   }
-#line 1605 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1610 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 11:
-#line 144 "cmFortranParser.y" /* yacc.c:1646  */
+#line 144 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1615 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1620 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 12:
-#line 149 "cmFortranParser.y" /* yacc.c:1646  */
+#line 149 "cmFortranParser.y" /* yacc.c:1652  */
     {
     if (cmsysString_strcasecmp((yyvsp[-4].string), "non_intrinsic") == 0) {
       cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
@@ -1624,139 +1629,139 @@
     free((yyvsp[-4].string));
     free((yyvsp[-2].string));
   }
-#line 1628 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1633 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 13:
-#line 157 "cmFortranParser.y" /* yacc.c:1646  */
+#line 157 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1638 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1643 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 14:
-#line 162 "cmFortranParser.y" /* yacc.c:1646  */
+#line 162 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1648 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1653 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 15:
-#line 167 "cmFortranParser.y" /* yacc.c:1646  */
+#line 167 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1658 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1663 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 16:
-#line 172 "cmFortranParser.y" /* yacc.c:1646  */
+#line 172 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1668 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1673 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 17:
-#line 177 "cmFortranParser.y" /* yacc.c:1646  */
+#line 177 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1678 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1683 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 18:
-#line 182 "cmFortranParser.y" /* yacc.c:1646  */
+#line 182 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1688 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1693 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 19:
-#line 187 "cmFortranParser.y" /* yacc.c:1646  */
+#line 187 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1698 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1703 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 20:
-#line 192 "cmFortranParser.y" /* yacc.c:1646  */
+#line 192 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
     free((yyvsp[-2].string));
   }
-#line 1708 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1713 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 21:
-#line 197 "cmFortranParser.y" /* yacc.c:1646  */
+#line 197 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleIf(parser);
   }
-#line 1717 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1722 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 22:
-#line 201 "cmFortranParser.y" /* yacc.c:1646  */
+#line 201 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleElif(parser);
   }
-#line 1726 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1731 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 23:
-#line 205 "cmFortranParser.y" /* yacc.c:1646  */
+#line 205 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleElse(parser);
   }
-#line 1735 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1740 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 24:
-#line 209 "cmFortranParser.y" /* yacc.c:1646  */
+#line 209 "cmFortranParser.y" /* yacc.c:1652  */
     {
     cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
     cmFortranParser_RuleEndif(parser);
   }
-#line 1744 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1749 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 48:
-#line 231 "cmFortranParser.y" /* yacc.c:1646  */
+#line 231 "cmFortranParser.y" /* yacc.c:1652  */
     { free ((yyvsp[0].string)); }
-#line 1750 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1755 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
   case 55:
-#line 238 "cmFortranParser.y" /* yacc.c:1646  */
+#line 238 "cmFortranParser.y" /* yacc.c:1652  */
     { free ((yyvsp[0].string)); }
-#line 1756 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1761 "cmFortranParser.cxx" /* yacc.c:1652  */
     break;
 
 
-#line 1760 "cmFortranParser.cxx" /* yacc.c:1646  */
+#line 1765 "cmFortranParser.cxx" /* yacc.c:1652  */
       default: break;
     }
   /* User semantic actions sometimes alter yychar, and that requires
@@ -1781,14 +1786,13 @@
   /* Now 'shift' the result of the reduction.  Determine what state
      that goes to, based on the state we popped back to and the rule
      number reduced by.  */
-
-  yyn = yyr1[yyn];
-
-  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
-  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
-    yystate = yytable[yystate];
-  else
-    yystate = yydefgoto[yyn - YYNTOKENS];
+  {
+    const int yylhs = yyr1[yyn] - YYNTOKENS;
+    const int yyi = yypgoto[yylhs] + *yyssp;
+    yystate = (0 <= yyi && yyi <= YYLAST && yycheck[yyi] == *yyssp
+               ? yytable[yyi]
+               : yydefgoto[yylhs]);
+  }
 
   goto yynewstate;
 
@@ -1872,12 +1876,10 @@
 | yyerrorlab -- error raised explicitly by YYERROR.  |
 `---------------------------------------------------*/
 yyerrorlab:
-
-  /* Pacify compilers like GCC when the user code never invokes
-     YYERROR and the label yyerrorlab therefore never appears in user
-     code.  */
-  if (/*CONSTCOND*/ 0)
-     goto yyerrorlab;
+  /* Pacify compilers when the user code never invokes YYERROR and the
+     label yyerrorlab therefore never appears in user code.  */
+  if (0)
+    YYERROR;
 
   /* Do not reclaim the symbols of the rule whose action triggered
      this YYERROR.  */
@@ -1940,6 +1942,7 @@
   yyresult = 0;
   goto yyreturn;
 
+
 /*-----------------------------------.
 | yyabortlab -- YYABORT comes here.  |
 `-----------------------------------*/
@@ -1947,6 +1950,7 @@
   yyresult = 1;
   goto yyreturn;
 
+
 #if !defined yyoverflow || YYERROR_VERBOSE
 /*-------------------------------------------------.
 | yyexhaustedlab -- memory exhaustion comes here.  |
@@ -1957,6 +1961,10 @@
   /* Fall through.  */
 #endif
 
+
+/*-----------------------------------------------------.
+| yyreturn -- parsing is finished, return the result.  |
+`-----------------------------------------------------*/
 yyreturn:
   if (yychar != YYEMPTY)
     {
@@ -1986,6 +1994,6 @@
 #endif
   return yyresult;
 }
-#line 249 "cmFortranParser.y" /* yacc.c:1906  */
+#line 249 "cmFortranParser.y" /* yacc.c:1918  */
 
 /* End of grammar */
diff --git a/Source/LexerParser/cmFortranParserTokens.h b/Source/LexerParser/cmFortranParserTokens.h
index 29c6d60..0da4c1c 100644
--- a/Source/LexerParser/cmFortranParserTokens.h
+++ b/Source/LexerParser/cmFortranParserTokens.h
@@ -1,8 +1,9 @@
-/* A Bison parser, made by GNU Bison 3.0.4.  */
+/* A Bison parser, made by GNU Bison 3.3.2.  */
 
 /* Bison interface for Yacc-like parsers in C
 
-   Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
+   Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -30,6 +31,9 @@
    This special exception was added by the Free Software Foundation in
    version 2.2 of Bison.  */
 
+/* Undocumented macros, especially those whose name start with YY_,
+   are private implementation details.  Do not rely on them.  */
+
 #ifndef YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
 # define YY_CMFORTRAN_YY_CMFORTRANPARSERTOKENS_H_INCLUDED
 /* Debug traces.  */
@@ -130,11 +134,11 @@
 
 union YYSTYPE
 {
-#line 73 "cmFortranParser.y" /* yacc.c:1909  */
+#line 73 "cmFortranParser.y" /* yacc.c:1921  */
 
   char* string;
 
-#line 138 "cmFortranParserTokens.h" /* yacc.c:1909  */
+#line 142 "cmFortranParserTokens.h" /* yacc.c:1921  */
 };
 
 typedef union YYSTYPE YYSTYPE;
diff --git a/Source/cmAddCompileDefinitionsCommand.h b/Source/cmAddCompileDefinitionsCommand.h
index e985dca..5f90ed9 100644
--- a/Source/cmAddCompileDefinitionsCommand.h
+++ b/Source/cmAddCompileDefinitionsCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -18,7 +20,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmAddCompileDefinitionsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmAddCompileDefinitionsCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmAddCompileOptionsCommand.h b/Source/cmAddCompileOptionsCommand.h
index 3d53d09..b34b7fc 100644
--- a/Source/cmAddCompileOptionsCommand.h
+++ b/Source/cmAddCompileOptionsCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -18,7 +20,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmAddCompileOptionsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmAddCompileOptionsCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmAddCustomCommandCommand.h b/Source/cmAddCustomCommandCommand.h
index 6af4f10..931aeab 100644
--- a/Source/cmAddCustomCommandCommand.h
+++ b/Source/cmAddCustomCommandCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmAddCustomCommandCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmAddCustomCommandCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmAddCustomTargetCommand.h b/Source/cmAddCustomTargetCommand.h
index 1a55116..db577bc 100644
--- a/Source/cmAddCustomTargetCommand.h
+++ b/Source/cmAddCustomTargetCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -25,7 +27,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmAddCustomTargetCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmAddCustomTargetCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmAddDefinitionsCommand.h b/Source/cmAddDefinitionsCommand.h
index 7b75638..0e32c83 100644
--- a/Source/cmAddDefinitionsCommand.h
+++ b/Source/cmAddDefinitionsCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmAddDefinitionsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmAddDefinitionsCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmAddDependenciesCommand.h b/Source/cmAddDependenciesCommand.h
index e10df71..ce912d3 100644
--- a/Source/cmAddDependenciesCommand.h
+++ b/Source/cmAddDependenciesCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmAddDependenciesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmAddDependenciesCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmAddExecutableCommand.h b/Source/cmAddExecutableCommand.h
index bdf607d..ec57c3f 100644
--- a/Source/cmAddExecutableCommand.h
+++ b/Source/cmAddExecutableCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmAddExecutableCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmAddExecutableCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmAddLibraryCommand.h b/Source/cmAddLibraryCommand.h
index aa21261..56dab41 100644
--- a/Source/cmAddLibraryCommand.h
+++ b/Source/cmAddLibraryCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmAddLibraryCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmAddLibraryCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmAddLinkOptionsCommand.h b/Source/cmAddLinkOptionsCommand.h
index 30fff00..8e46be6 100644
--- a/Source/cmAddLinkOptionsCommand.h
+++ b/Source/cmAddLinkOptionsCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -18,7 +20,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmAddLinkOptionsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmAddLinkOptionsCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmAddSubDirectoryCommand.h b/Source/cmAddSubDirectoryCommand.h
index 0ea4423..664334e 100644
--- a/Source/cmAddSubDirectoryCommand.h
+++ b/Source/cmAddSubDirectoryCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -25,7 +27,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmAddSubDirectoryCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmAddSubDirectoryCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmAddTestCommand.h b/Source/cmAddTestCommand.h
index bea3f3d..3d37d2b 100644
--- a/Source/cmAddTestCommand.h
+++ b/Source/cmAddTestCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmAddTestCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmAddTestCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmAlgorithms.h b/Source/cmAlgorithms.h
index d1e32b0..cf71052 100644
--- a/Source/cmAlgorithms.h
+++ b/Source/cmAlgorithms.h
@@ -8,10 +8,10 @@
 #include "cmRange.h"
 
 #include "cm_kwiml.h"
+#include "cm_string_view.hxx"
 #include <algorithm>
 #include <functional>
 #include <iterator>
-#include <memory>
 #include <sstream>
 #include <string.h>
 #include <string>
@@ -19,44 +19,6 @@
 #include <utility>
 #include <vector>
 
-inline bool cmHasLiteralPrefixImpl(const std::string& str1, const char* str2,
-                                   size_t N)
-{
-  return strncmp(str1.c_str(), str2, N) == 0;
-}
-
-inline bool cmHasLiteralPrefixImpl(const char* str1, const char* str2,
-                                   size_t N)
-{
-  return strncmp(str1, str2, N) == 0;
-}
-
-inline bool cmHasLiteralSuffixImpl(const std::string& str1, const char* str2,
-                                   size_t N)
-{
-  size_t len = str1.size();
-  return len >= N && strcmp(str1.c_str() + len - N, str2) == 0;
-}
-
-inline bool cmHasLiteralSuffixImpl(const char* str1, const char* str2,
-                                   size_t N)
-{
-  size_t len = strlen(str1);
-  return len >= N && strcmp(str1 + len - N, str2) == 0;
-}
-
-template <typename T, size_t N>
-bool cmHasLiteralPrefix(const T& str1, const char (&str2)[N])
-{
-  return cmHasLiteralPrefixImpl(str1, str2, N - 1);
-}
-
-template <typename T, size_t N>
-bool cmHasLiteralSuffix(const T& str1, const char (&str2)[N])
-{
-  return cmHasLiteralSuffixImpl(str1, str2, N - 1);
-}
-
 struct cmStrCmp
 {
   cmStrCmp(const char* test)
@@ -315,23 +277,55 @@
   return std::reverse_iterator<Iter>(it);
 }
 
-inline bool cmHasPrefix(std::string const& str, std::string const& prefix)
+/** Returns true if string @a str starts with the character @a prefix.  **/
+inline bool cmHasPrefix(cm::string_view str, char prefix)
 {
-  if (str.size() < prefix.size()) {
-    return false;
-  }
+  return !str.empty() && (str.front() == prefix);
+}
+
+/** Returns true if string @a str starts with string @a prefix.  **/
+inline bool cmHasPrefix(cm::string_view str, cm::string_view prefix)
+{
   return str.compare(0, prefix.size(), prefix) == 0;
 }
 
-inline bool cmHasSuffix(const std::string& str, const std::string& suffix)
+/** Returns true if string @a str starts with string @a prefix.  **/
+template <size_t N>
+inline bool cmHasLiteralPrefix(cm::string_view str, const char (&prefix)[N])
 {
-  if (str.size() < suffix.size()) {
-    return false;
-  }
-  return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+  return cmHasPrefix(str, cm::string_view(prefix, N - 1));
 }
 
-inline void cmStripSuffixIfExists(std::string& str, const std::string& suffix)
+/** Returns true if string @a str ends with the character @a suffix.  **/
+inline bool cmHasSuffix(cm::string_view str, char suffix)
+{
+  return !str.empty() && (str.back() == suffix);
+}
+
+/** Returns true if string @a str ends with string @a suffix.  **/
+inline bool cmHasSuffix(cm::string_view str, cm::string_view suffix)
+{
+  return str.size() >= suffix.size() &&
+    str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
+}
+
+/** Returns true if string @a str ends with string @a suffix.  **/
+template <size_t N>
+inline bool cmHasLiteralSuffix(cm::string_view str, const char (&suffix)[N])
+{
+  return cmHasSuffix(str, cm::string_view(suffix, N - 1));
+}
+
+/** Removes an existing suffix character of from the string @a str.  **/
+inline void cmStripSuffixIfExists(std::string& str, char suffix)
+{
+  if (cmHasSuffix(str, suffix)) {
+    str.pop_back();
+  }
+}
+
+/** Removes an existing suffix string of from the string @a str.  **/
+inline void cmStripSuffixIfExists(std::string& str, cm::string_view suffix)
 {
   if (cmHasSuffix(str, suffix)) {
     str.resize(str.size() - suffix.size());
@@ -340,20 +334,6 @@
 
 namespace cm {
 
-#if defined(CMake_HAVE_CXX_MAKE_UNIQUE)
-
-using std::make_unique;
-
-#else
-
-template <typename T, typename... Args>
-std::unique_ptr<T> make_unique(Args&&... args)
-{
-  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
-}
-
-#endif
-
 #if __cplusplus >= 201703L || defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
 
 using std::size;
diff --git a/Source/cmAuxSourceDirectoryCommand.cxx b/Source/cmAuxSourceDirectoryCommand.cxx
index 106e7a7..c1a6e7f 100644
--- a/Source/cmAuxSourceDirectoryCommand.cxx
+++ b/Source/cmAuxSourceDirectoryCommand.cxx
@@ -74,6 +74,6 @@
     sourceListValue += ";";
   }
   sourceListValue += cmJoin(files, ";");
-  this->Makefile->AddDefinition(args[1], sourceListValue.c_str());
+  this->Makefile->AddDefinition(args[1], sourceListValue);
   return true;
 }
diff --git a/Source/cmAuxSourceDirectoryCommand.h b/Source/cmAuxSourceDirectoryCommand.h
index 3742e3e..973a464 100644
--- a/Source/cmAuxSourceDirectoryCommand.h
+++ b/Source/cmAuxSourceDirectoryCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -27,7 +29,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmAuxSourceDirectoryCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmAuxSourceDirectoryCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmBinUtilsLinuxELFLinker.cxx b/Source/cmBinUtilsLinuxELFLinker.cxx
index 4fb15f2..86846cb 100644
--- a/Source/cmBinUtilsLinuxELFLinker.cxx
+++ b/Source/cmBinUtilsLinuxELFLinker.cxx
@@ -2,7 +2,7 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 
 #include "cmBinUtilsLinuxELFLinker.h"
-#include "cmAlgorithms.h"
+
 #include "cmBinUtilsLinuxELFObjdumpGetRuntimeDependenciesTool.h"
 #include "cmLDConfigLDConfigTool.h"
 #include "cmMakefile.h"
@@ -12,9 +12,10 @@
 
 #include <cmsys/RegularExpression.hxx>
 
-#include <memory>
 #include <sstream>
 
+#include "cm_memory.hxx"
+
 static std::string ReplaceOrigin(const std::string& rpath,
                                  const std::string& origin)
 {
diff --git a/Source/cmBinUtilsMacOSMachOLinker.cxx b/Source/cmBinUtilsMacOSMachOLinker.cxx
index e219847..ac93155 100644
--- a/Source/cmBinUtilsMacOSMachOLinker.cxx
+++ b/Source/cmBinUtilsMacOSMachOLinker.cxx
@@ -12,6 +12,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 cmBinUtilsMacOSMachOLinker::cmBinUtilsMacOSMachOLinker(
   cmRuntimeDependencyArchive* archive)
   : cmBinUtilsLinker(archive)
diff --git a/Source/cmBinUtilsWindowsPELinker.cxx b/Source/cmBinUtilsWindowsPELinker.cxx
index 796e9ed..31602c4 100644
--- a/Source/cmBinUtilsWindowsPELinker.cxx
+++ b/Source/cmBinUtilsWindowsPELinker.cxx
@@ -2,16 +2,17 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 
 #include "cmBinUtilsWindowsPELinker.h"
-#include "cmAlgorithms.h"
+
 #include "cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool.h"
 #include "cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool.h"
 #include "cmRuntimeDependencyArchive.h"
 #include "cmSystemTools.h"
 
-#include <memory>
 #include <sstream>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #ifdef _WIN32
 #  include <windows.h>
 #endif
diff --git a/Source/cmBreakCommand.h b/Source/cmBreakCommand.h
index 3b18567..e6f218e 100644
--- a/Source/cmBreakCommand.h
+++ b/Source/cmBreakCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmBreakCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmBreakCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmBuildCommand.cxx b/Source/cmBuildCommand.cxx
index 428a0b2..e9e1d49 100644
--- a/Source/cmBuildCommand.cxx
+++ b/Source/cmBuildCommand.cxx
@@ -92,7 +92,7 @@
     this->Makefile->GetGlobalGenerator()->GenerateCMakeBuildCommand(
       target, configuration, "", this->Makefile->IgnoreErrorsCMP0061());
 
-  this->Makefile->AddDefinition(variable, makecommand.c_str());
+  this->Makefile->AddDefinition(variable, makecommand);
 
   return true;
 }
diff --git a/Source/cmBuildCommand.h b/Source/cmBuildCommand.h
index e0529a4..d373103 100644
--- a/Source/cmBuildCommand.h
+++ b/Source/cmBuildCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmBuildCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmBuildCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmBuildNameCommand.h b/Source/cmBuildNameCommand.h
index 4bb72d1..bd2d146 100644
--- a/Source/cmBuildNameCommand.h
+++ b/Source/cmBuildNameCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,7 +17,10 @@
 class cmBuildNameCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmBuildNameCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmBuildNameCommand>();
+  }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
 };
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 54f08bb..b4cd2a5 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -55,7 +55,7 @@
     result_list += value;
   }
 
-  this->Makefile->AddDefinition(variable, result_list.c_str());
+  this->Makefile->AddDefinition(variable, result_list);
 
   return true;
 }
diff --git a/Source/cmCMakeHostSystemInformationCommand.h b/Source/cmCMakeHostSystemInformationCommand.h
index b871641..8ea2d55 100644
--- a/Source/cmCMakeHostSystemInformationCommand.h
+++ b/Source/cmCMakeHostSystemInformationCommand.h
@@ -9,6 +9,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -28,9 +30,9 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    return new cmCMakeHostSystemInformationCommand;
+    return cm::make_unique<cmCMakeHostSystemInformationCommand>();
   }
 
   /**
diff --git a/Source/cmCMakeMinimumRequired.cxx b/Source/cmCMakeMinimumRequired.cxx
index 4b4bca2..f2eae38 100644
--- a/Source/cmCMakeMinimumRequired.cxx
+++ b/Source/cmCMakeMinimumRequired.cxx
@@ -61,8 +61,7 @@
   }
 
   // Save the required version string.
-  this->Makefile->AddDefinition("CMAKE_MINIMUM_REQUIRED_VERSION",
-                                version_min.c_str());
+  this->Makefile->AddDefinition("CMAKE_MINIMUM_REQUIRED_VERSION", version_min);
 
   // Get the current version number.
   unsigned int current_major = cmVersion::GetMajorVersion();
diff --git a/Source/cmCMakeMinimumRequired.h b/Source/cmCMakeMinimumRequired.h
index f9b61e1..3881133 100644
--- a/Source/cmCMakeMinimumRequired.h
+++ b/Source/cmCMakeMinimumRequired.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmCMakeMinimumRequired; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmCMakeMinimumRequired>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmCMakePolicyCommand.cxx b/Source/cmCMakePolicyCommand.cxx
index 8da5ef7..ce046fc 100644
--- a/Source/cmCMakePolicyCommand.cxx
+++ b/Source/cmCMakePolicyCommand.cxx
@@ -209,8 +209,7 @@
   }
 
   // Lookup the policy warning.
-  this->Makefile->AddDefinition(var,
-                                cmPolicies::GetPolicyWarning(pid).c_str());
+  this->Makefile->AddDefinition(var, cmPolicies::GetPolicyWarning(pid));
 
   return true;
 }
diff --git a/Source/cmCMakePolicyCommand.h b/Source/cmCMakePolicyCommand.h
index cca1406..919402c 100644
--- a/Source/cmCMakePolicyCommand.h
+++ b/Source/cmCMakePolicyCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmCMakePolicyCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmCMakePolicyCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index 255a8e6..80ca898 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -65,8 +65,10 @@
 
 void CCONV cmAddDefinition(void* arg, const char* name, const char* value)
 {
-  cmMakefile* mf = static_cast<cmMakefile*>(arg);
-  mf->AddDefinition(name, value);
+  if (value) {
+    cmMakefile* mf = static_cast<cmMakefile*>(arg);
+    mf->AddDefinition(name, value);
+  }
 }
 
 /* Add a definition to this makefile and the global cmake cache. */
@@ -421,7 +423,7 @@
     // Assume all arguments are quoted.
     lff.Arguments.emplace_back(args[i], cmListFileArgument::Quoted, 0);
   }
-  cmExecutionStatus status;
+  cmExecutionStatus status(*mf);
   return mf->ExecuteCommand(lff, status);
 }
 
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 536ca35..83e3eff 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -15,7 +15,6 @@
 #include <ctype.h>
 #include <iostream>
 #include <map>
-#include <memory>
 #include <sstream>
 #include <stdio.h>
 #include <stdlib.h>
@@ -30,6 +29,8 @@
 #  include <unistd.h> // IWYU pragma: keep
 #endif
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmCTestBuildAndTestHandler.h"
 #include "cmCTestBuildHandler.h"
@@ -1098,9 +1099,10 @@
   cmProcessOutput processOutput(encoding);
   std::string strdata;
   cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
-             "   Each . represents " << tick_len << " bytes of output"
-                                     << std::endl
-                                     << "    " << std::flush);
+             "   Each . represents " << tick_len
+                                     << " bytes of output\n"
+                                        "    "
+                                     << std::flush);
   while (cmsysProcess_WaitForData(cp, &data, &length, nullptr)) {
     processOutput.DecodeText(data, length, strdata);
     for (char& cc : strdata) {
@@ -1115,8 +1117,7 @@
       if (tick % tick_line_len == 0 && tick > 0) {
         cmCTestLog(this, HANDLER_PROGRESS_OUTPUT,
                    "  Size: " << int((double(output.size()) / 1024.0) + 1)
-                              << "K" << std::endl
-                              << "    " << std::flush);
+                              << "K\n    " << std::flush);
       }
     }
     cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
@@ -1324,18 +1325,14 @@
     if (output) {
       *output += outerr;
     }
-    cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
-               outerr << std::endl
-                      << std::flush);
+    cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl);
   } else if (result == cmsysProcess_State_Error) {
     std::string outerr = "\n*** ERROR executing: ";
     outerr += cmsysProcess_GetErrorString(cp);
     if (output) {
       *output += outerr;
     }
-    cmCTestLog(this, HANDLER_VERBOSE_OUTPUT,
-               outerr << std::endl
-                      << std::flush);
+    cmCTestLog(this, HANDLER_VERBOSE_OUTPUT, outerr << std::endl);
   }
   cmsysProcess_Delete(cp);
 
@@ -3077,11 +3074,11 @@
         } else {
           *this->Impl->OutputLogFile << cmCTestStringLogType[logType];
         }
-        *this->Impl->OutputLogFile << "] " << std::endl << std::flush;
+        *this->Impl->OutputLogFile << "] " << std::endl;
       }
       *this->Impl->OutputLogFile << msg << std::flush;
       if (logType != this->Impl->OutputLogFileLastTag) {
-        *this->Impl->OutputLogFile << std::endl << std::flush;
+        *this->Impl->OutputLogFile << std::endl;
         this->Impl->OutputLogFileLastTag = logType;
       }
     }
@@ -3194,7 +3191,7 @@
   if (!process_output.empty()) {
     test_outputs.append(process_output.data(), process_output.size());
   }
-  cmCTestLog(this, HANDLER_OUTPUT, test_outputs << std::endl << std::flush);
+  cmCTestLog(this, HANDLER_OUTPUT, test_outputs << std::endl);
 }
 
 bool cmCTest::CompressString(std::string& str)
diff --git a/Source/cmCommand.cxx b/Source/cmCommand.cxx
index d349c91..0c2734e 100644
--- a/Source/cmCommand.cxx
+++ b/Source/cmCommand.cxx
@@ -2,11 +2,19 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmCommand.h"
 
+#include <utility>
+
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 
-class cmExecutionStatus;
 struct cmListFileArgument;
 
+void cmCommand::SetExecutionStatus(cmExecutionStatus* status)
+{
+  this->Status = status;
+  this->Makefile = &status->GetMakefile();
+}
+
 bool cmCommand::InvokeInitialPass(const std::vector<cmListFileArgument>& args,
                                   cmExecutionStatus& status)
 {
@@ -19,15 +27,33 @@
   return this->InitialPass(expandedArguments, status);
 }
 
-const char* cmCommand::GetError()
-{
-  if (this->Error.empty()) {
-    return "unknown error.";
-  }
-  return this->Error.c_str();
-}
-
 void cmCommand::SetError(const std::string& e)
 {
-  this->Error = e;
+  this->Status->SetError(e);
+}
+
+cmLegacyCommandWrapper::cmLegacyCommandWrapper(std::unique_ptr<cmCommand> cmd)
+  : Command(std::move(cmd))
+{
+}
+
+cmLegacyCommandWrapper::cmLegacyCommandWrapper(
+  cmLegacyCommandWrapper const& other)
+  : Command(other.Command->Clone())
+{
+}
+
+cmLegacyCommandWrapper& cmLegacyCommandWrapper::operator=(
+  cmLegacyCommandWrapper const& other)
+{
+  this->Command = other.Command->Clone();
+  return *this;
+}
+
+bool cmLegacyCommandWrapper::operator()(
+  std::vector<cmListFileArgument> const& args, cmExecutionStatus& status) const
+{
+  auto cmd = this->Command->Clone();
+  cmd->SetExecutionStatus(&status);
+  return cmd->InvokeInitialPass(args, status);
 }
diff --git a/Source/cmCommand.h b/Source/cmCommand.h
index 9ccd773..bcb178d 100644
--- a/Source/cmCommand.h
+++ b/Source/cmCommand.h
@@ -5,6 +5,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -41,16 +42,18 @@
   /**
    * Specify the makefile.
    */
-  void SetMakefile(cmMakefile* m) { this->Makefile = m; }
   cmMakefile* GetMakefile() { return this->Makefile; }
 
+  void SetExecutionStatus(cmExecutionStatus* s);
+  cmExecutionStatus* GetExecutionStatus() { return this->Status; };
+
   /**
    * This is called by the cmMakefile when the command is first
    * encountered in the CMakeLists.txt file.  It expands the command's
    * arguments and then invokes the InitialPass.
    */
-  virtual bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
-                                 cmExecutionStatus& status);
+  bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
+                         cmExecutionStatus& status);
 
   /**
    * This is called when the command is first encountered in
@@ -60,27 +63,9 @@
                            cmExecutionStatus&) = 0;
 
   /**
-   * This is called at the end after all the information
-   * specified by the command is accumulated. Most commands do
-   * not implement this method.  At this point, reading and
-   * writing to the cache can be done.
-   */
-  virtual void FinalPass() {}
-
-  /**
-   * Does this command have a final pass?  Query after InitialPass.
-   */
-  virtual bool HasFinalPass() const { return false; }
-
-  /**
    * This is a virtual constructor for the command.
    */
-  virtual cmCommand* Clone() = 0;
-
-  /**
-   * Return the last error string.
-   */
-  const char* GetError();
+  virtual std::unique_ptr<cmCommand> Clone() = 0;
 
   /**
    * Set the error message
@@ -91,7 +76,25 @@
   cmMakefile* Makefile = nullptr;
 
 private:
-  std::string Error;
+  cmExecutionStatus* Status = nullptr;
+};
+
+class cmLegacyCommandWrapper
+{
+public:
+  explicit cmLegacyCommandWrapper(std::unique_ptr<cmCommand> cmd);
+
+  cmLegacyCommandWrapper(cmLegacyCommandWrapper const& other);
+  cmLegacyCommandWrapper& operator=(cmLegacyCommandWrapper const& other);
+
+  cmLegacyCommandWrapper(cmLegacyCommandWrapper&&) = default;
+  cmLegacyCommandWrapper& operator=(cmLegacyCommandWrapper&&) = default;
+
+  bool operator()(std::vector<cmListFileArgument> const& args,
+                  cmExecutionStatus& status) const;
+
+private:
+  std::unique_ptr<cmCommand> Command;
 };
 
 #endif
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index 63c5397..f351ff8 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -1,5 +1,8 @@
 /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
    file Copyright.txt or https://cmake.org/licensing for details.  */
+
+#include "cm_memory.hxx"
+
 #include "cmCommands.h"
 #include "cmPolicies.h"
 #include "cmState.h"
@@ -17,6 +20,7 @@
 #include "cmBuildCommand.h"
 #include "cmCMakeMinimumRequired.h"
 #include "cmCMakePolicyCommand.h"
+#include "cmCommand.h"
 #include "cmConfigureFileCommand.h"
 #include "cmContinueCommand.h"
 #include "cmCreateTestSourceList.h"
@@ -112,52 +116,64 @@
 
 void GetScriptingCommands(cmState* state)
 {
-  state->AddBuiltinCommand("break", new cmBreakCommand);
+  state->AddBuiltinCommand("break", cm::make_unique<cmBreakCommand>());
   state->AddBuiltinCommand("cmake_minimum_required",
-                           new cmCMakeMinimumRequired);
-  state->AddBuiltinCommand("cmake_policy", new cmCMakePolicyCommand);
-  state->AddBuiltinCommand("configure_file", new cmConfigureFileCommand);
-  state->AddBuiltinCommand("continue", new cmContinueCommand);
-  state->AddBuiltinCommand("exec_program", new cmExecProgramCommand);
-  state->AddBuiltinCommand("execute_process", new cmExecuteProcessCommand);
-  state->AddBuiltinCommand("file", new cmFileCommand);
-  state->AddBuiltinCommand("find_file", new cmFindFileCommand);
-  state->AddBuiltinCommand("find_library", new cmFindLibraryCommand);
-  state->AddBuiltinCommand("find_package", new cmFindPackageCommand);
-  state->AddBuiltinCommand("find_path", new cmFindPathCommand);
-  state->AddBuiltinCommand("find_program", new cmFindProgramCommand);
-  state->AddBuiltinCommand("foreach", new cmForEachCommand);
-  state->AddBuiltinCommand("function", new cmFunctionCommand);
+                           cm::make_unique<cmCMakeMinimumRequired>());
+  state->AddBuiltinCommand("cmake_policy",
+                           cm::make_unique<cmCMakePolicyCommand>());
+  state->AddBuiltinCommand("configure_file",
+                           cm::make_unique<cmConfigureFileCommand>());
+  state->AddBuiltinCommand("continue", cm::make_unique<cmContinueCommand>());
+  state->AddBuiltinCommand("exec_program",
+                           cm::make_unique<cmExecProgramCommand>());
+  state->AddBuiltinCommand("execute_process",
+                           cm::make_unique<cmExecuteProcessCommand>());
+  state->AddBuiltinCommand("file", cm::make_unique<cmFileCommand>());
+  state->AddBuiltinCommand("find_file", cm::make_unique<cmFindFileCommand>());
+  state->AddBuiltinCommand("find_library",
+                           cm::make_unique<cmFindLibraryCommand>());
+  state->AddBuiltinCommand("find_package",
+                           cm::make_unique<cmFindPackageCommand>());
+  state->AddBuiltinCommand("find_path", cm::make_unique<cmFindPathCommand>());
+  state->AddBuiltinCommand("find_program",
+                           cm::make_unique<cmFindProgramCommand>());
+  state->AddBuiltinCommand("foreach", cm::make_unique<cmForEachCommand>());
+  state->AddBuiltinCommand("function", cm::make_unique<cmFunctionCommand>());
   state->AddBuiltinCommand("get_cmake_property",
-                           new cmGetCMakePropertyCommand);
+                           cm::make_unique<cmGetCMakePropertyCommand>());
   state->AddBuiltinCommand("get_directory_property",
-                           new cmGetDirectoryPropertyCommand);
+                           cm::make_unique<cmGetDirectoryPropertyCommand>());
   state->AddBuiltinCommand("get_filename_component",
-                           new cmGetFilenameComponentCommand);
-  state->AddBuiltinCommand("get_property", new cmGetPropertyCommand);
-  state->AddBuiltinCommand("if", new cmIfCommand);
-  state->AddBuiltinCommand("include", new cmIncludeCommand);
-  state->AddBuiltinCommand("include_guard", new cmIncludeGuardCommand);
-  state->AddBuiltinCommand("list", new cmListCommand);
-  state->AddBuiltinCommand("macro", new cmMacroCommand);
-  state->AddBuiltinCommand("make_directory", new cmMakeDirectoryCommand);
-  state->AddBuiltinCommand("mark_as_advanced", new cmMarkAsAdvancedCommand);
-  state->AddBuiltinCommand("math", new cmMathCommand);
-  state->AddBuiltinCommand("message", new cmMessageCommand);
-  state->AddBuiltinCommand("option", new cmOptionCommand);
+                           cm::make_unique<cmGetFilenameComponentCommand>());
+  state->AddBuiltinCommand("get_property",
+                           cm::make_unique<cmGetPropertyCommand>());
+  state->AddBuiltinCommand("if", cmIfCommand);
+  state->AddBuiltinCommand("include", cm::make_unique<cmIncludeCommand>());
+  state->AddBuiltinCommand("include_guard",
+                           cm::make_unique<cmIncludeGuardCommand>());
+  state->AddBuiltinCommand("list", cm::make_unique<cmListCommand>());
+  state->AddBuiltinCommand("macro", cm::make_unique<cmMacroCommand>());
+  state->AddBuiltinCommand("make_directory",
+                           cm::make_unique<cmMakeDirectoryCommand>());
+  state->AddBuiltinCommand("mark_as_advanced",
+                           cm::make_unique<cmMarkAsAdvancedCommand>());
+  state->AddBuiltinCommand("math", cm::make_unique<cmMathCommand>());
+  state->AddBuiltinCommand("message", cm::make_unique<cmMessageCommand>());
+  state->AddBuiltinCommand("option", cm::make_unique<cmOptionCommand>());
   state->AddBuiltinCommand("cmake_parse_arguments",
-                           new cmParseArgumentsCommand);
-  state->AddBuiltinCommand("return", new cmReturnCommand);
+                           cm::make_unique<cmParseArgumentsCommand>());
+  state->AddBuiltinCommand("return", cmReturnCommand);
   state->AddBuiltinCommand("separate_arguments",
-                           new cmSeparateArgumentsCommand);
-  state->AddBuiltinCommand("set", new cmSetCommand);
+                           cm::make_unique<cmSeparateArgumentsCommand>());
+  state->AddBuiltinCommand("set", cm::make_unique<cmSetCommand>());
   state->AddBuiltinCommand("set_directory_properties",
-                           new cmSetDirectoryPropertiesCommand);
-  state->AddBuiltinCommand("set_property", new cmSetPropertyCommand);
-  state->AddBuiltinCommand("site_name", new cmSiteNameCommand);
-  state->AddBuiltinCommand("string", new cmStringCommand);
-  state->AddBuiltinCommand("unset", new cmUnsetCommand);
-  state->AddBuiltinCommand("while", new cmWhileCommand);
+                           cm::make_unique<cmSetDirectoryPropertiesCommand>());
+  state->AddBuiltinCommand("set_property",
+                           cm::make_unique<cmSetPropertyCommand>());
+  state->AddBuiltinCommand("site_name", cm::make_unique<cmSiteNameCommand>());
+  state->AddBuiltinCommand("string", cm::make_unique<cmStringCommand>());
+  state->AddBuiltinCommand("unset", cm::make_unique<cmUnsetCommand>());
+  state->AddBuiltinCommand("while", cmWhileCommand);
 
   state->AddUnexpectedCommand(
     "else",
@@ -195,17 +211,21 @@
     "match the opening WHILE command.");
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
-  state->AddBuiltinCommand("cmake_host_system_information",
-                           new cmCMakeHostSystemInformationCommand);
-  state->AddBuiltinCommand("remove", new cmRemoveCommand);
-  state->AddBuiltinCommand("variable_watch", new cmVariableWatchCommand);
-  state->AddBuiltinCommand("write_file", new cmWriteFileCommand);
+  state->AddBuiltinCommand(
+    "cmake_host_system_information",
+    cm::make_unique<cmCMakeHostSystemInformationCommand>());
+  state->AddBuiltinCommand("remove", cm::make_unique<cmRemoveCommand>());
+  state->AddBuiltinCommand("variable_watch",
+                           cm::make_unique<cmVariableWatchCommand>());
+  state->AddBuiltinCommand("write_file",
+                           cm::make_unique<cmWriteFileCommand>());
 
   state->AddDisallowedCommand(
-    "build_name", new cmBuildNameCommand, cmPolicies::CMP0036,
+    "build_name", cm::make_unique<cmBuildNameCommand>(), cmPolicies::CMP0036,
     "The build_name command should not be called; see CMP0036.");
   state->AddDisallowedCommand(
-    "use_mangled_mesa", new cmUseMangledMesaCommand, cmPolicies::CMP0030,
+    "use_mangled_mesa", cm::make_unique<cmUseMangledMesaCommand>(),
+    cmPolicies::CMP0030,
     "The use_mangled_mesa command should not be called; see CMP0030.");
 
 #endif
@@ -214,100 +234,130 @@
 void GetProjectCommands(cmState* state)
 {
   state->AddBuiltinCommand("add_custom_command",
-                           new cmAddCustomCommandCommand);
-  state->AddBuiltinCommand("add_custom_target", new cmAddCustomTargetCommand);
-  state->AddBuiltinCommand("add_definitions", new cmAddDefinitionsCommand);
-  state->AddBuiltinCommand("add_dependencies", new cmAddDependenciesCommand);
-  state->AddBuiltinCommand("add_executable", new cmAddExecutableCommand);
-  state->AddBuiltinCommand("add_library", new cmAddLibraryCommand);
-  state->AddBuiltinCommand("add_subdirectory", new cmAddSubDirectoryCommand);
-  state->AddBuiltinCommand("add_test", new cmAddTestCommand);
-  state->AddBuiltinCommand("build_command", new cmBuildCommand);
+                           cm::make_unique<cmAddCustomCommandCommand>());
+  state->AddBuiltinCommand("add_custom_target",
+                           cm::make_unique<cmAddCustomTargetCommand>());
+  state->AddBuiltinCommand("add_definitions",
+                           cm::make_unique<cmAddDefinitionsCommand>());
+  state->AddBuiltinCommand("add_dependencies",
+                           cm::make_unique<cmAddDependenciesCommand>());
+  state->AddBuiltinCommand("add_executable",
+                           cm::make_unique<cmAddExecutableCommand>());
+  state->AddBuiltinCommand("add_library",
+                           cm::make_unique<cmAddLibraryCommand>());
+  state->AddBuiltinCommand("add_subdirectory",
+                           cm::make_unique<cmAddSubDirectoryCommand>());
+  state->AddBuiltinCommand("add_test", cm::make_unique<cmAddTestCommand>());
+  state->AddBuiltinCommand("build_command", cm::make_unique<cmBuildCommand>());
   state->AddBuiltinCommand("create_test_sourcelist",
-                           new cmCreateTestSourceList);
-  state->AddBuiltinCommand("define_property", new cmDefinePropertyCommand);
-  state->AddBuiltinCommand("enable_language", new cmEnableLanguageCommand);
-  state->AddBuiltinCommand("enable_testing", new cmEnableTestingCommand);
+                           cm::make_unique<cmCreateTestSourceList>());
+  state->AddBuiltinCommand("define_property",
+                           cm::make_unique<cmDefinePropertyCommand>());
+  state->AddBuiltinCommand("enable_language",
+                           cm::make_unique<cmEnableLanguageCommand>());
+  state->AddBuiltinCommand("enable_testing", cmEnableTestingCommand);
   state->AddBuiltinCommand("get_source_file_property",
-                           new cmGetSourceFilePropertyCommand);
+                           cm::make_unique<cmGetSourceFilePropertyCommand>());
   state->AddBuiltinCommand("get_target_property",
-                           new cmGetTargetPropertyCommand);
-  state->AddBuiltinCommand("get_test_property", new cmGetTestPropertyCommand);
+                           cm::make_unique<cmGetTargetPropertyCommand>());
+  state->AddBuiltinCommand("get_test_property",
+                           cm::make_unique<cmGetTestPropertyCommand>());
   state->AddBuiltinCommand("include_directories",
-                           new cmIncludeDirectoryCommand);
-  state->AddBuiltinCommand("include_regular_expression",
-                           new cmIncludeRegularExpressionCommand);
-  state->AddBuiltinCommand("install", new cmInstallCommand);
-  state->AddBuiltinCommand("install_files", new cmInstallFilesCommand);
-  state->AddBuiltinCommand("install_targets", new cmInstallTargetsCommand);
-  state->AddBuiltinCommand("link_directories", new cmLinkDirectoriesCommand);
-  state->AddBuiltinCommand("project", new cmProjectCommand);
-  state->AddBuiltinCommand("set_source_files_properties",
-                           new cmSetSourceFilesPropertiesCommand);
+                           cm::make_unique<cmIncludeDirectoryCommand>());
+  state->AddBuiltinCommand(
+    "include_regular_expression",
+    cm::make_unique<cmIncludeRegularExpressionCommand>());
+  state->AddBuiltinCommand("install", cm::make_unique<cmInstallCommand>());
+  state->AddBuiltinCommand("install_files",
+                           cm::make_unique<cmInstallFilesCommand>());
+  state->AddBuiltinCommand("install_targets",
+                           cm::make_unique<cmInstallTargetsCommand>());
+  state->AddBuiltinCommand("link_directories",
+                           cm::make_unique<cmLinkDirectoriesCommand>());
+  state->AddBuiltinCommand("project", cm::make_unique<cmProjectCommand>());
+  state->AddBuiltinCommand(
+    "set_source_files_properties",
+    cm::make_unique<cmSetSourceFilesPropertiesCommand>());
   state->AddBuiltinCommand("set_target_properties",
-                           new cmSetTargetPropertiesCommand);
+                           cm::make_unique<cmSetTargetPropertiesCommand>());
   state->AddBuiltinCommand("set_tests_properties",
-                           new cmSetTestsPropertiesCommand);
-  state->AddBuiltinCommand("subdirs", new cmSubdirCommand);
-  state->AddBuiltinCommand("target_compile_definitions",
-                           new cmTargetCompileDefinitionsCommand);
+                           cm::make_unique<cmSetTestsPropertiesCommand>());
+  state->AddBuiltinCommand("subdirs", cm::make_unique<cmSubdirCommand>());
+  state->AddBuiltinCommand(
+    "target_compile_definitions",
+    cm::make_unique<cmTargetCompileDefinitionsCommand>());
   state->AddBuiltinCommand("target_compile_features",
-                           new cmTargetCompileFeaturesCommand);
+                           cm::make_unique<cmTargetCompileFeaturesCommand>());
   state->AddBuiltinCommand("target_compile_options",
-                           new cmTargetCompileOptionsCommand);
-  state->AddBuiltinCommand("target_include_directories",
-                           new cmTargetIncludeDirectoriesCommand);
+                           cm::make_unique<cmTargetCompileOptionsCommand>());
+  state->AddBuiltinCommand(
+    "target_include_directories",
+    cm::make_unique<cmTargetIncludeDirectoriesCommand>());
   state->AddBuiltinCommand("target_link_libraries",
-                           new cmTargetLinkLibrariesCommand);
-  state->AddBuiltinCommand("target_sources", new cmTargetSourcesCommand);
-  state->AddBuiltinCommand("try_compile", new cmTryCompileCommand);
-  state->AddBuiltinCommand("try_run", new cmTryRunCommand);
+                           cm::make_unique<cmTargetLinkLibrariesCommand>());
+  state->AddBuiltinCommand("target_sources",
+                           cm::make_unique<cmTargetSourcesCommand>());
+  state->AddBuiltinCommand("try_compile",
+                           cm::make_unique<cmTryCompileCommand>());
+  state->AddBuiltinCommand("try_run", cm::make_unique<cmTryRunCommand>());
 
 #if defined(CMAKE_BUILD_WITH_CMAKE)
   state->AddBuiltinCommand("add_compile_definitions",
-                           new cmAddCompileDefinitionsCommand);
+                           cm::make_unique<cmAddCompileDefinitionsCommand>());
   state->AddBuiltinCommand("add_compile_options",
-                           new cmAddCompileOptionsCommand);
+                           cm::make_unique<cmAddCompileOptionsCommand>());
   state->AddBuiltinCommand("aux_source_directory",
-                           new cmAuxSourceDirectoryCommand);
-  state->AddBuiltinCommand("export", new cmExportCommand);
-  state->AddBuiltinCommand("fltk_wrap_ui", new cmFLTKWrapUICommand);
-  state->AddBuiltinCommand("include_external_msproject",
-                           new cmIncludeExternalMSProjectCommand);
-  state->AddBuiltinCommand("install_programs", new cmInstallProgramsCommand);
-  state->AddBuiltinCommand("add_link_options", new cmAddLinkOptionsCommand);
-  state->AddBuiltinCommand("link_libraries", new cmLinkLibrariesCommand);
+                           cm::make_unique<cmAuxSourceDirectoryCommand>());
+  state->AddBuiltinCommand("export", cm::make_unique<cmExportCommand>());
+  state->AddBuiltinCommand("fltk_wrap_ui",
+                           cm::make_unique<cmFLTKWrapUICommand>());
+  state->AddBuiltinCommand(
+    "include_external_msproject",
+    cm::make_unique<cmIncludeExternalMSProjectCommand>());
+  state->AddBuiltinCommand("install_programs",
+                           cm::make_unique<cmInstallProgramsCommand>());
+  state->AddBuiltinCommand("add_link_options",
+                           cm::make_unique<cmAddLinkOptionsCommand>());
+  state->AddBuiltinCommand("link_libraries",
+                           cm::make_unique<cmLinkLibrariesCommand>());
   state->AddBuiltinCommand("target_link_options",
-                           new cmTargetLinkOptionsCommand);
+                           cm::make_unique<cmTargetLinkOptionsCommand>());
   state->AddBuiltinCommand("target_link_directories",
-                           new cmTargetLinkDirectoriesCommand);
-  state->AddBuiltinCommand("load_cache", new cmLoadCacheCommand);
-  state->AddBuiltinCommand("qt_wrap_cpp", new cmQTWrapCPPCommand);
-  state->AddBuiltinCommand("qt_wrap_ui", new cmQTWrapUICommand);
+                           cm::make_unique<cmTargetLinkDirectoriesCommand>());
+  state->AddBuiltinCommand("load_cache",
+                           cm::make_unique<cmLoadCacheCommand>());
+  state->AddBuiltinCommand("qt_wrap_cpp",
+                           cm::make_unique<cmQTWrapCPPCommand>());
+  state->AddBuiltinCommand("qt_wrap_ui", cm::make_unique<cmQTWrapUICommand>());
   state->AddBuiltinCommand("remove_definitions",
-                           new cmRemoveDefinitionsCommand);
-  state->AddBuiltinCommand("source_group", new cmSourceGroupCommand);
+                           cm::make_unique<cmRemoveDefinitionsCommand>());
+  state->AddBuiltinCommand("source_group",
+                           cm::make_unique<cmSourceGroupCommand>());
 
   state->AddDisallowedCommand(
-    "export_library_dependencies", new cmExportLibraryDependenciesCommand,
-    cmPolicies::CMP0033,
+    "export_library_dependencies",
+    cm::make_unique<cmExportLibraryDependenciesCommand>(), cmPolicies::CMP0033,
     "The export_library_dependencies command should not be called; "
     "see CMP0033.");
   state->AddDisallowedCommand(
-    "load_command", new cmLoadCommandCommand, cmPolicies::CMP0031,
+    "load_command", cm::make_unique<cmLoadCommandCommand>(),
+    cmPolicies::CMP0031,
     "The load_command command should not be called; see CMP0031.");
   state->AddDisallowedCommand(
-    "output_required_files", new cmOutputRequiredFilesCommand,
+    "output_required_files", cm::make_unique<cmOutputRequiredFilesCommand>(),
     cmPolicies::CMP0032,
     "The output_required_files command should not be called; see CMP0032.");
   state->AddDisallowedCommand(
-    "subdir_depends", new cmSubdirDependsCommand, cmPolicies::CMP0029,
+    "subdir_depends", cm::make_unique<cmSubdirDependsCommand>(),
+    cmPolicies::CMP0029,
     "The subdir_depends command should not be called; see CMP0029.");
   state->AddDisallowedCommand(
-    "utility_source", new cmUtilitySourceCommand, cmPolicies::CMP0034,
+    "utility_source", cm::make_unique<cmUtilitySourceCommand>(),
+    cmPolicies::CMP0034,
     "The utility_source command should not be called; see CMP0034.");
   state->AddDisallowedCommand(
-    "variable_requires", new cmVariableRequiresCommand, cmPolicies::CMP0035,
+    "variable_requires", cm::make_unique<cmVariableRequiresCommand>(),
+    cmPolicies::CMP0035,
     "The variable_requires command should not be called; see CMP0035.");
 #endif
 }
diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx
index a7618c7..54fc54c 100644
--- a/Source/cmComputeLinkDepends.cxx
+++ b/Source/cmComputeLinkDepends.cxx
@@ -23,6 +23,8 @@
 #include <string.h>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 /*
 
 This file computes an ordered list of link items to use when linking a
diff --git a/Source/cmComputeLinkInformation.cxx b/Source/cmComputeLinkInformation.cxx
index b366ebb..f696f28 100644
--- a/Source/cmComputeLinkInformation.cxx
+++ b/Source/cmComputeLinkInformation.cxx
@@ -268,10 +268,6 @@
     return;
   }
 
-  // Check whether we should use an import library for linking a target.
-  this->UseImportLibrary =
-    this->Makefile->IsDefinitionSet("CMAKE_IMPORT_LIBRARY_SUFFIX");
-
   // Check whether we should skip dependencies on shared library files.
   this->LinkDependsNoShared =
     this->Target->GetPropertyAsBool("LINK_DEPENDS_NO_SHARED");
@@ -280,7 +276,7 @@
   // to use when creating a plugin (module) that obtains symbols from
   // the program that will load it.
   this->LoaderFlag = nullptr;
-  if (!this->UseImportLibrary &&
+  if (!this->Target->IsDLLPlatform() &&
       this->Target->GetType() == cmStateEnums::MODULE_LIBRARY) {
     std::string loader_flag_var = "CMAKE_SHARED_MODULE_LOADER_";
     loader_flag_var += this->LinkLanguage;
@@ -493,9 +489,7 @@
     std::set<cmGeneratorTarget const*> const& wrongItems =
       cld.GetOldWrongConfigItems();
     for (cmGeneratorTarget const* tgt : wrongItems) {
-      bool implib = (this->UseImportLibrary &&
-                     (tgt->GetType() == cmStateEnums::SHARED_LIBRARY));
-      cmStateEnums::ArtifactType artifact = implib
+      cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(this->Config)
         ? cmStateEnums::ImportLibraryArtifact
         : cmStateEnums::RuntimeBinaryArtifact;
       this->OldLinkDirItems.push_back(
@@ -578,7 +572,7 @@
   // Compute the proper name to use to link this library.
   const std::string& config = this->Config;
   bool impexe = (tgt && tgt->IsExecutableWithExports());
-  if (impexe && !this->UseImportLibrary && !this->LoaderFlag) {
+  if (impexe && !tgt->HasImportLibrary(config) && !this->LoaderFlag) {
     // Skip linking to executables on platforms with no import
     // libraries or loader flags.
     return;
@@ -592,7 +586,7 @@
       // platform.  Add it now.
       std::string linkItem;
       linkItem = this->LoaderFlag;
-      cmStateEnums::ArtifactType artifact = this->UseImportLibrary
+      cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config)
         ? cmStateEnums::ImportLibraryArtifact
         : cmStateEnums::RuntimeBinaryArtifact;
 
@@ -616,15 +610,21 @@
       // Its object-files should already have been extracted for linking.
     } else {
       // Decide whether to use an import library.
-      bool implib =
-        (this->UseImportLibrary &&
-         (impexe || tgt->GetType() == cmStateEnums::SHARED_LIBRARY));
-      cmStateEnums::ArtifactType artifact = implib
+      cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(config)
         ? cmStateEnums::ImportLibraryArtifact
         : cmStateEnums::RuntimeBinaryArtifact;
 
       // Pass the full path to the target file.
       std::string lib = tgt->GetFullPath(config, artifact, true);
+      if (tgt->Target->IsAIX() && cmHasLiteralSuffix(lib, "-NOTFOUND") &&
+          artifact == cmStateEnums::ImportLibraryArtifact) {
+        // This is an imported executable on AIX that has ENABLE_EXPORTS
+        // but not IMPORTED_IMPLIB.  CMake used to produce and accept such
+        // imported executables on AIX before we taught it to use linker
+        // import files.  For compatibility, simply skip linking to this
+        // executable as we did before.  It works with runtime linking.
+        return;
+      }
       if (!this->LinkDependsNoShared ||
           tgt->GetType() != cmStateEnums::SHARED_LIBRARY) {
         this->Depends.push_back(lib);
@@ -694,7 +694,7 @@
   // linked will be able to find it.
   std::string lib;
   if (tgt) {
-    cmStateEnums::ArtifactType artifact = this->UseImportLibrary
+    cmStateEnums::ArtifactType artifact = tgt->HasImportLibrary(this->Config)
       ? cmStateEnums::ImportLibraryArtifact
       : cmStateEnums::RuntimeBinaryArtifact;
     lib = tgt->GetFullPath(this->Config, artifact);
diff --git a/Source/cmComputeLinkInformation.h b/Source/cmComputeLinkInformation.h
index 863639c..3be2c7f 100644
--- a/Source/cmComputeLinkInformation.h
+++ b/Source/cmComputeLinkInformation.h
@@ -179,7 +179,6 @@
   bool OldLinkDirMode;
   bool OpenBSD;
   bool LinkDependsNoShared;
-  bool UseImportLibrary;
   bool RuntimeUseChrpath;
   bool NoSONameUsesPath;
   bool LinkWithRuntimePath;
diff --git a/Source/cmConditionEvaluator.cxx b/Source/cmConditionEvaluator.cxx
index e7e91c1..2907f4a 100644
--- a/Source/cmConditionEvaluator.cxx
+++ b/Source/cmConditionEvaluator.cxx
@@ -4,6 +4,7 @@
 
 #include "cmsys/RegularExpression.hxx"
 #include <algorithm>
+#include <functional>
 #include <sstream>
 #include <stdio.h>
 #include <stdlib.h>
@@ -17,7 +18,6 @@
 #include "cmSystemTools.h"
 #include "cmake.h"
 
-class cmCommand;
 class cmTest;
 
 static std::string const keyAND = "AND";
@@ -452,7 +452,7 @@
       }
       // does a command exist
       if (this->IsKeyword(keyCOMMAND, *arg) && argP1 != newArgs.end()) {
-        cmCommand* command =
+        cmState::Command command =
           this->Makefile.GetState()->GetCommand(argP1->c_str());
         this->HandlePredicate(command != nullptr, reducible, arg, newArgs,
                               argP1, argP2);
diff --git a/Source/cmConfigureFileCommand.h b/Source/cmConfigureFileCommand.h
index 5603c50..b3a99d7 100644
--- a/Source/cmConfigureFileCommand.h
+++ b/Source/cmConfigureFileCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 #include "cmNewLineStyle.h"
 
@@ -16,7 +18,10 @@
 class cmConfigureFileCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmConfigureFileCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmConfigureFileCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmContinueCommand.h b/Source/cmContinueCommand.h
index d383d1d..a85010a 100644
--- a/Source/cmContinueCommand.h
+++ b/Source/cmContinueCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmContinueCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmContinueCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index f12ef0b..d780af6 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -932,7 +932,7 @@
                                      cmStateEnums::INTERNAL);
 
   if (!outputVariable.empty()) {
-    this->Makefile->AddDefinition(outputVariable, output.c_str());
+    this->Makefile->AddDefinition(outputVariable, output);
   }
 
   if (this->SrcFileSignature) {
@@ -961,8 +961,7 @@
     }
 
     if (!copyFileError.empty()) {
-      this->Makefile->AddDefinition(copyFileError,
-                                    copyFileErrorMessage.c_str());
+      this->Makefile->AddDefinition(copyFileError, copyFileErrorMessage);
     }
   }
   return res;
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
index b78493f..427db72 100644
--- a/Source/cmCreateTestSourceList.cxx
+++ b/Source/cmCreateTestSourceList.cxx
@@ -125,16 +125,15 @@
   }
   if (!extraInclude.empty()) {
     this->Makefile->AddDefinition("CMAKE_TESTDRIVER_EXTRA_INCLUDES",
-                                  extraInclude.c_str());
+                                  extraInclude);
   }
   if (!function.empty()) {
-    this->Makefile->AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION",
-                                  function.c_str());
+    this->Makefile->AddDefinition("CMAKE_TESTDRIVER_ARGVC_FUNCTION", function);
   }
   this->Makefile->AddDefinition("CMAKE_FORWARD_DECLARE_TESTS",
-                                forwardDeclareCode.c_str());
+                                forwardDeclareCode);
   this->Makefile->AddDefinition("CMAKE_FUNCTION_TABLE_ENTIRES",
-                                functionMapCode.c_str());
+                                functionMapCode);
   bool res = true;
   if (!this->Makefile->ConfigureFile(configFile, driver, false, true, false)) {
     res = false;
@@ -154,6 +153,6 @@
     sourceListValue += *i;
   }
 
-  this->Makefile->AddDefinition(sourceList, sourceListValue.c_str());
+  this->Makefile->AddDefinition(sourceList, sourceListValue);
   return res;
 }
diff --git a/Source/cmCreateTestSourceList.h b/Source/cmCreateTestSourceList.h
index 005b32c..5aa6af4 100644
--- a/Source/cmCreateTestSourceList.h
+++ b/Source/cmCreateTestSourceList.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmCreateTestSourceList; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmCreateTestSourceList>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmCryptoHash.cxx b/Source/cmCryptoHash.cxx
index 4310eed..5e919af 100644
--- a/Source/cmCryptoHash.cxx
+++ b/Source/cmCryptoHash.cxx
@@ -2,13 +2,13 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmCryptoHash.h"
 
-#include "cmAlgorithms.h"
 #include "cm_kwiml.h"
 #include "cm_rhash.h"
 #include "cmsys/FStream.hxx"
+
 #include <string.h>
 
-#include <memory>
+#include "cm_memory.hxx"
 
 static unsigned int const cmCryptoHashAlgoToId[] = {
   /* clang-format needs this comment to break after the opening brace */
diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx
index 5e8731a..758a69a 100644
--- a/Source/cmCustomCommandGenerator.cxx
+++ b/Source/cmCustomCommandGenerator.cxx
@@ -25,6 +25,7 @@
   , OldStyle(cc.GetEscapeOldStyle())
   , MakeVars(cc.GetEscapeAllowMakeVars())
   , GE(new cmGeneratorExpression(cc.GetBacktrace()))
+  , EmulatorsWithArguments(cc.GetCommandLines().size())
 {
   const cmCustomCommandLines& cmdlines = this->CC.GetCommandLines();
   for (cmCustomCommandLine const& cmdline : cmdlines) {
@@ -107,7 +108,6 @@
         continue;
       }
 
-      this->EmulatorsWithArguments.emplace_back();
       cmSystemTools::ExpandListArgument(emulator_property,
                                         this->EmulatorsWithArguments[c]);
     }
diff --git a/Source/cmDefinePropertyCommand.h b/Source/cmDefinePropertyCommand.h
index a9c1856..36f97df 100644
--- a/Source/cmDefinePropertyCommand.h
+++ b/Source/cmDefinePropertyCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,7 +17,10 @@
 class cmDefinePropertyCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmDefinePropertyCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmDefinePropertyCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx
index 894447c..42e70d6 100644
--- a/Source/cmDefinitions.cxx
+++ b/Source/cmDefinitions.cxx
@@ -13,10 +13,12 @@
                                                      StackIter end, bool raise)
 {
   assert(begin != end);
-  MapType::iterator i = begin->Map.find(key);
-  if (i != begin->Map.end()) {
-    i->second.Used = true;
-    return i->second;
+  {
+    MapType::iterator it = begin->Map.find(key);
+    if (it != begin->Map.end()) {
+      it->second.Used = true;
+      return it->second;
+    }
   }
   StackIter it = begin;
   ++it;
@@ -27,14 +29,14 @@
   if (!raise) {
     return def;
   }
-  return begin->Map.insert(MapType::value_type(key, def)).first->second;
+  return begin->Map.emplace(key, def).first->second;
 }
 
 const std::string* cmDefinitions::Get(const std::string& key, StackIter begin,
                                       StackIter end)
 {
   Def const& def = cmDefinitions::GetInternal(key, begin, end, false);
-  return def.Exists ? &def : nullptr;
+  return def.Exists ? &def.Value : nullptr;
 }
 
 void cmDefinitions::Raise(const std::string& key, StackIter begin,
@@ -47,19 +49,23 @@
                            StackIter end)
 {
   for (StackIter it = begin; it != end; ++it) {
-    MapType::const_iterator i = it->Map.find(key);
-    if (i != it->Map.end()) {
+    if (it->Map.find(key) != it->Map.end()) {
       return true;
     }
   }
   return false;
 }
 
-void cmDefinitions::Set(const std::string& key, const char* value)
+void cmDefinitions::Set(const std::string& key, cm::string_view value)
 {
   this->Map[key] = Def(value);
 }
 
+void cmDefinitions::Unset(const std::string& key)
+{
+  this->Map[key] = Def();
+}
+
 std::vector<std::string> cmDefinitions::UnusedKeys() const
 {
   std::vector<std::string> keys;
@@ -97,8 +103,8 @@
 std::vector<std::string> cmDefinitions::ClosureKeys(StackIter begin,
                                                     StackIter end)
 {
-  std::set<std::string> bound;
   std::vector<std::string> defined;
+  std::set<std::string> bound;
 
   for (StackIter it = begin; it != end; ++it) {
     defined.reserve(defined.size() + it->Map.size());
diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h
index 6c252be..4d8810a 100644
--- a/Source/cmDefinitions.h
+++ b/Source/cmDefinitions.h
@@ -5,12 +5,14 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include "cm_string_view.hxx"
+
+#include "cmLinkedTree.h"
+
 #include <string>
 #include <unordered_map>
 #include <vector>
 
-#include "cmLinkedTree.h"
-
 /** \class cmDefinitions
  * \brief Store a scope of variable definitions for CMake language.
  *
@@ -30,8 +32,11 @@
 
   static bool HasKey(const std::string& key, StackIter begin, StackIter end);
 
-  /** Set (or unset if null) a value associated with a key.  */
-  void Set(const std::string& key, const char* value);
+  /** Set a value associated with a key.  */
+  void Set(const std::string& key, cm::string_view value);
+
+  /** Unset a definition.  */
+  void Unset(const std::string& key);
 
   std::vector<std::string> UnusedKeys() const;
 
@@ -40,24 +45,17 @@
   static cmDefinitions MakeClosure(StackIter begin, StackIter end);
 
 private:
-  // String with existence boolean.
-  struct Def : public std::string
+  /** String with existence boolean.  */
+  struct Def
   {
-  private:
-    typedef std::string std_string;
-
   public:
     Def() = default;
-    Def(const char* v)
-      : std_string(v ? v : "")
-      , Exists(v ? true : false)
-    {
-    }
-    Def(const std_string& v)
-      : std_string(v)
+    Def(cm::string_view value)
+      : Value(value)
       , Exists(true)
     {
     }
+    std::string Value;
     bool Exists = false;
     bool Used = false;
   };
diff --git a/Source/cmDisallowedCommand.cxx b/Source/cmDisallowedCommand.cxx
index 418d98c..aa1f90b 100644
--- a/Source/cmDisallowedCommand.cxx
+++ b/Source/cmDisallowedCommand.cxx
@@ -24,8 +24,6 @@
       return true;
   }
 
-  this->Command->SetMakefile(this->GetMakefile());
-  bool const ret = this->Command->InitialPass(args, status);
-  this->SetError(this->Command->GetError());
-  return ret;
+  this->Command->SetExecutionStatus(this->GetExecutionStatus());
+  return this->Command->InitialPass(args, status);
 }
diff --git a/Source/cmDisallowedCommand.h b/Source/cmDisallowedCommand.h
index d85c00f..e07f255 100644
--- a/Source/cmDisallowedCommand.h
+++ b/Source/cmDisallowedCommand.h
@@ -6,8 +6,11 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <string>
+#include <utility>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 #include "cmPolicies.h"
 
@@ -16,31 +19,27 @@
 class cmDisallowedCommand : public cmCommand
 {
 public:
-  cmDisallowedCommand(cmCommand* command, cmPolicies::PolicyID policy,
-                      const char* message)
-    : Command(command)
+  cmDisallowedCommand(std::unique_ptr<cmCommand> command,
+                      cmPolicies::PolicyID policy, const char* message)
+    : Command(std::move(command))
     , Policy(policy)
     , Message(message)
   {
   }
 
-  ~cmDisallowedCommand() override { delete this->Command; }
+  ~cmDisallowedCommand() override = default;
 
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    return new cmDisallowedCommand(this->Command->Clone(), this->Policy,
-                                   this->Message);
+    return cm::make_unique<cmDisallowedCommand>(this->Command->Clone(),
+                                                this->Policy, this->Message);
   }
 
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
 
-  void FinalPass() override { this->Command->FinalPass(); }
-
-  bool HasFinalPass() const override { return this->Command->HasFinalPass(); }
-
 private:
-  cmCommand* Command;
+  std::unique_ptr<cmCommand> Command;
   cmPolicies::PolicyID Policy;
   const char* Message;
 };
diff --git a/Source/cmELF.cxx b/Source/cmELF.cxx
index 51eb814..096016d 100644
--- a/Source/cmELF.cxx
+++ b/Source/cmELF.cxx
@@ -4,6 +4,7 @@
 
 #include "cmAlgorithms.h"
 #include "cm_kwiml.h"
+#include "cm_memory.hxx"
 #include "cmsys/FStream.hxx"
 #include <map>
 #include <memory>
@@ -109,10 +110,10 @@
   };
 
   // Construct and take ownership of the file stream object.
-  cmELFInternal(cmELF* external, std::unique_ptr<cmsys::ifstream>& fin,
+  cmELFInternal(cmELF* external, std::unique_ptr<std::istream> fin,
                 ByteOrderType order)
     : External(external)
-    , Stream(*fin.release())
+    , Stream(std::move(fin))
     , ByteOrder(order)
     , ELFType(cmELF::FileTypeInvalid)
   {
@@ -132,7 +133,7 @@
   }
 
   // Destruct and delete the file stream object.
-  virtual ~cmELFInternal() { delete &this->Stream; }
+  virtual ~cmELFInternal() = default;
 
   // Forward to the per-class implementation.
   virtual unsigned int GetNumberOfSections() const = 0;
@@ -171,7 +172,7 @@
   cmELF* External;
 
   // The stream from which to read.
-  std::istream& Stream;
+  std::unique_ptr<std::istream> Stream;
 
   // The byte order of the ELF file.
   ByteOrderType ByteOrder;
@@ -233,7 +234,7 @@
   typedef typename Types::tagtype tagtype;
 
   // Construct with a stream and byte swap indicator.
-  cmELFInternalImpl(cmELF* external, std::unique_ptr<cmsys::ifstream>& fin,
+  cmELFInternalImpl(cmELF* external, std::unique_ptr<std::istream> fin,
                     ByteOrderType order);
 
   // Return the number of sections as specified by the ELF header.
@@ -352,7 +353,7 @@
   bool Read(ELF_Ehdr& x)
   {
     // Read the header from the file.
-    if (!this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x))) {
+    if (!this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x))) {
       return false;
     }
 
@@ -382,26 +383,26 @@
   }
   bool Read(ELF_Shdr& x)
   {
-    if (this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) &&
+    if (this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x)) &&
         this->NeedSwap) {
       ByteSwap(x);
     }
-    return !this->Stream.fail();
+    return !this->Stream->fail();
   }
   bool Read(ELF_Dyn& x)
   {
-    if (this->Stream.read(reinterpret_cast<char*>(&x), sizeof(x)) &&
+    if (this->Stream->read(reinterpret_cast<char*>(&x), sizeof(x)) &&
         this->NeedSwap) {
       ByteSwap(x);
     }
-    return !this->Stream.fail();
+    return !this->Stream->fail();
   }
 
   bool LoadSectionHeader(ELF_Half i)
   {
     // Read the section header from the file.
-    this->Stream.seekg(this->ELFHeader.e_shoff +
-                       this->ELFHeader.e_shentsize * i);
+    this->Stream->seekg(this->ELFHeader.e_shoff +
+                        this->ELFHeader.e_shentsize * i);
     if (!this->Read(this->SectionHeaders[i])) {
       return false;
     }
@@ -426,9 +427,10 @@
 };
 
 template <class Types>
-cmELFInternalImpl<Types>::cmELFInternalImpl(
-  cmELF* external, std::unique_ptr<cmsys::ifstream>& fin, ByteOrderType order)
-  : cmELFInternal(external, fin, order)
+cmELFInternalImpl<Types>::cmELFInternalImpl(cmELF* external,
+                                            std::unique_ptr<std::istream> fin,
+                                            ByteOrderType order)
+  : cmELFInternal(external, std::move(fin), order)
 {
   // Read the main header.
   if (!this->Read(this->ELFHeader)) {
@@ -510,7 +512,7 @@
   // Read each entry.
   for (int j = 0; j < n; ++j) {
     // Seek to the beginning of the section entry.
-    this->Stream.seekg(sec.sh_offset + sec.sh_entsize * j);
+    this->Stream->seekg(sec.sh_offset + sec.sh_entsize * j);
     ELF_Dyn& dyn = this->DynamicSectionEntries[j];
 
     // Try reading the entry.
@@ -630,7 +632,7 @@
       unsigned long first = static_cast<unsigned long>(dyn.d_un.d_val);
       unsigned long last = first;
       unsigned long end = static_cast<unsigned long>(strtab.sh_size);
-      this->Stream.seekg(strtab.sh_offset + first);
+      this->Stream->seekg(strtab.sh_offset + first);
 
       // Read the string.  It may be followed by more than one NULL
       // terminator.  Count the total size of the region allocated to
@@ -639,7 +641,7 @@
       // assumption.
       bool terminated = false;
       char c;
-      while (last != end && this->Stream.get(c) && !(terminated && c)) {
+      while (last != end && this->Stream->get(c) && !(terminated && c)) {
         ++last;
         if (c) {
           se.Value += c;
@@ -649,7 +651,7 @@
       }
 
       // Make sure the whole value was read.
-      if (!this->Stream) {
+      if (!(*this->Stream)) {
         this->SetErrorMessage("Dynamic section specifies unreadable RPATH.");
         se.Value = "";
         return nullptr;
@@ -679,10 +681,9 @@
 #endif
 
 cmELF::cmELF(const char* fname)
-  : Internal(nullptr)
 {
   // Try to open the file.
-  std::unique_ptr<cmsys::ifstream> fin(new cmsys::ifstream(fname));
+  auto fin = cm::make_unique<cmsys::ifstream>(fname);
 
   // Quit now if the file could not be opened.
   if (!fin || !*fin) {
@@ -725,12 +726,14 @@
   // parser implementation.
   if (ident[EI_CLASS] == ELFCLASS32) {
     // 32-bit ELF
-    this->Internal = new cmELFInternalImpl<cmELFTypes32>(this, fin, order);
+    this->Internal = cm::make_unique<cmELFInternalImpl<cmELFTypes32>>(
+      this, std::move(fin), order);
   }
 #ifndef _SCO_DS
   else if (ident[EI_CLASS] == ELFCLASS64) {
     // 64-bit ELF
-    this->Internal = new cmELFInternalImpl<cmELFTypes64>(this, fin, order);
+    this->Internal = cm::make_unique<cmELFInternalImpl<cmELFTypes64>>(
+      this, std::move(fin), order);
   }
 #endif
   else {
@@ -739,10 +742,7 @@
   }
 }
 
-cmELF::~cmELF()
-{
-  delete this->Internal;
-}
+cmELF::~cmELF() = default;
 
 bool cmELF::Valid() const
 {
diff --git a/Source/cmELF.h b/Source/cmELF.h
index 987f0c3..afef654 100644
--- a/Source/cmELF.h
+++ b/Source/cmELF.h
@@ -6,6 +6,7 @@
 #include "cmConfigure.h" // IWYU pragma: keep
 
 #include <iosfwd>
+#include <memory>
 #include <string>
 #include <utility>
 #include <vector>
@@ -108,7 +109,7 @@
 private:
   friend class cmELFInternal;
   bool Valid() const;
-  cmELFInternal* Internal;
+  std::unique_ptr<cmELFInternal> Internal;
   std::string ErrorMessage;
 };
 
diff --git a/Source/cmEnableLanguageCommand.h b/Source/cmEnableLanguageCommand.h
index 97645a9..dc43e34 100644
--- a/Source/cmEnableLanguageCommand.h
+++ b/Source/cmEnableLanguageCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -26,7 +28,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmEnableLanguageCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmEnableLanguageCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmEnableTestingCommand.cxx b/Source/cmEnableTestingCommand.cxx
index 6a64450..89212c8 100644
--- a/Source/cmEnableTestingCommand.cxx
+++ b/Source/cmEnableTestingCommand.cxx
@@ -2,15 +2,12 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmEnableTestingCommand.h"
 
+#include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 
-class cmExecutionStatus;
-
-// we do this in the final pass so that we now the subdirs have all
-// been defined
-bool cmEnableTestingCommand::InitialPass(std::vector<std::string> const&,
-                                         cmExecutionStatus&)
+bool cmEnableTestingCommand(std::vector<std::string> const&,
+                            cmExecutionStatus& status)
 {
-  this->Makefile->AddDefinition("CMAKE_TESTING_ENABLED", "1");
+  status.GetMakefile().AddDefinition("CMAKE_TESTING_ENABLED", "1");
   return true;
 }
diff --git a/Source/cmEnableTestingCommand.h b/Source/cmEnableTestingCommand.h
index 88a17b9..e4593f2 100644
--- a/Source/cmEnableTestingCommand.h
+++ b/Source/cmEnableTestingCommand.h
@@ -8,11 +8,9 @@
 #include <string>
 #include <vector>
 
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmEnableTestingCommand
+/**
  * \brief Enable testing for this directory and below.
  *
  * Produce the output testfile. This produces a file in the build directory
@@ -25,20 +23,7 @@
  * Note that CTest expects to find this file in the build directory root;
  * therefore, this command should be in the source directory root too.
  */
-class cmEnableTestingCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  cmCommand* Clone() override { return new cmEnableTestingCommand; }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const&,
-                   cmExecutionStatus&) override;
-};
+bool cmEnableTestingCommand(std::vector<std::string> const&,
+                            cmExecutionStatus&);
 
 #endif
diff --git a/Source/cmExecProgramCommand.cxx b/Source/cmExecProgramCommand.cxx
index 4b559e7..bc1d173 100644
--- a/Source/cmExecProgramCommand.cxx
+++ b/Source/cmExecProgramCommand.cxx
@@ -103,7 +103,7 @@
     }
 
     std::string coutput = std::string(output, first, last - first + 1);
-    this->Makefile->AddDefinition(output_variable, coutput.c_str());
+    this->Makefile->AddDefinition(output_variable, coutput);
   }
 
   if (!return_variable.empty()) {
diff --git a/Source/cmExecProgramCommand.h b/Source/cmExecProgramCommand.h
index ae0fa9b..70f833a 100644
--- a/Source/cmExecProgramCommand.h
+++ b/Source/cmExecProgramCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 #include "cmProcessOutput.h"
 
@@ -27,7 +29,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmExecProgramCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmExecProgramCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 121f33f..8d91f43 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -8,7 +8,6 @@
 #include <algorithm>
 #include <ctype.h> /* isspace */
 #include <iostream>
-#include <memory>
 #include <stdio.h>
 #include <vector>
 
@@ -333,7 +332,7 @@
           }
         }
         this->Makefile->AddDefinition(arguments.ResultsVariable,
-                                      cmJoin(res, ";").c_str());
+                                      cmJoin(res, ";"));
       } break;
       case cmsysProcess_State_Exception:
         this->Makefile->AddDefinition(arguments.ResultsVariable,
diff --git a/Source/cmExecuteProcessCommand.h b/Source/cmExecuteProcessCommand.h
index b415deb..1d5445f 100644
--- a/Source/cmExecuteProcessCommand.h
+++ b/Source/cmExecuteProcessCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmExecuteProcessCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmExecuteProcessCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h
index 56199dd..bcacc2f 100644
--- a/Source/cmExecutionStatus.h
+++ b/Source/cmExecutionStatus.h
@@ -3,6 +3,11 @@
 #ifndef cmExecutionStatus_h
 #define cmExecutionStatus_h
 
+#include <cmConfigure.h> // IWYU pragma: keep
+#include <string>
+
+class cmMakefile;
+
 /** \class cmExecutionStatus
  * \brief Superclass for all command status classes
  *
@@ -11,14 +16,26 @@
 class cmExecutionStatus
 {
 public:
+  cmExecutionStatus(cmMakefile& makefile)
+    : Makefile(makefile)
+    , Error("unknown error.")
+  {
+  }
+
   void Clear()
   {
+    this->Error = "unknown error.";
     this->ReturnInvoked = false;
     this->BreakInvoked = false;
     this->ContinueInvoked = false;
     this->NestedError = false;
   }
 
+  cmMakefile& GetMakefile() { return this->Makefile; }
+
+  void SetError(std::string const& e) { this->Error = e; }
+  std::string const& GetError() const { return this->Error; }
+
   void SetReturnInvoked() { this->ReturnInvoked = true; }
   bool GetReturnInvoked() const { return this->ReturnInvoked; }
 
@@ -32,6 +49,8 @@
   bool GetNestedError() const { return this->NestedError; }
 
 private:
+  cmMakefile& Makefile;
+  std::string Error;
   bool ReturnInvoked = false;
   bool BreakInvoked = false;
   bool ContinueInvoked = false;
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 5800629..de3e0e2 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -236,14 +236,15 @@
     }
 
     // Add the import library for windows DLLs.
-    if (target->HasImportLibrary(config) &&
-        mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+    if (target->HasImportLibrary(config)) {
       std::string prop = "IMPORTED_IMPLIB";
       prop += suffix;
       std::string value =
         target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact);
-      target->GetImplibGNUtoMS(config, value, value,
-                               "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
+      if (mf->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+        target->GetImplibGNUtoMS(config, value, value,
+                                 "${CMAKE_IMPORT_LIBRARY_SUFFIX}");
+      }
       properties[prop] = value;
     }
   }
diff --git a/Source/cmExportCommand.h b/Source/cmExportCommand.h
index 99f9932..50463af 100644
--- a/Source/cmExportCommand.h
+++ b/Source/cmExportCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -18,7 +20,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmExportCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmExportCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index e1c098d..29afc9f 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -20,11 +20,12 @@
 
 #include "cmsys/FStream.hxx"
 #include <assert.h>
-#include <memory>
 #include <sstream>
 #include <string.h>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 static std::string cmExportFileGeneratorEscape(std::string const& str)
 {
   // Escape a property value for writing into a .cmake file.
diff --git a/Source/cmExportLibraryDependenciesCommand.cxx b/Source/cmExportLibraryDependenciesCommand.cxx
index 2e86533..8f2fff5 100644
--- a/Source/cmExportLibraryDependenciesCommand.cxx
+++ b/Source/cmExportLibraryDependenciesCommand.cxx
@@ -4,10 +4,10 @@
 
 #include "cmsys/FStream.hxx"
 #include <map>
-#include <memory>
 #include <utility>
 
-#include "cmAlgorithms.h"
+#include "cm_memory.hxx"
+
 #include "cmGeneratedFileStream.h"
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
@@ -19,57 +19,31 @@
 
 class cmExecutionStatus;
 
-bool cmExportLibraryDependenciesCommand::InitialPass(
-  std::vector<std::string> const& args, cmExecutionStatus&)
-{
-  if (args.empty()) {
-    this->SetError("called with incorrect number of arguments");
-    return false;
-  }
-
-  // store the arguments for the final pass
-  this->Filename = args[0];
-  this->Append = false;
-  if (args.size() > 1) {
-    if (args[1] == "APPEND") {
-      this->Append = true;
-    }
-  }
-  return true;
-}
-
-void cmExportLibraryDependenciesCommand::FinalPass()
-{
-  // export_library_dependencies() shouldn't modify anything
-  // ensure this by calling a const method
-  this->ConstFinalPass();
-}
-
-void cmExportLibraryDependenciesCommand::ConstFinalPass() const
+static void FinalAction(cmMakefile& makefile, std::string const& filename,
+                        bool append)
 {
   // Use copy-if-different if not appending.
   std::unique_ptr<cmsys::ofstream> foutPtr;
-  if (this->Append) {
+  if (append) {
     const auto openmodeApp = std::ios::app;
-    foutPtr =
-      cm::make_unique<cmsys::ofstream>(this->Filename.c_str(), openmodeApp);
+    foutPtr = cm::make_unique<cmsys::ofstream>(filename.c_str(), openmodeApp);
   } else {
     std::unique_ptr<cmGeneratedFileStream> ap(
-      new cmGeneratedFileStream(this->Filename, true));
+      new cmGeneratedFileStream(filename, true));
     ap->SetCopyIfDifferent(true);
     foutPtr = std::move(ap);
   }
   std::ostream& fout = *foutPtr;
 
   if (!fout) {
-    cmSystemTools::Error("Error Writing " + this->Filename);
+    cmSystemTools::Error("Error Writing " + filename);
     cmSystemTools::ReportLastSystemError("");
     return;
   }
 
   // Collect dependency information about all library targets built in
   // the project.
-  cmake* cm = this->Makefile->GetCMakeInstance();
+  cmake* cm = makefile.GetCMakeInstance();
   cmGlobalGenerator* global = cm->GetGlobalGenerator();
   const std::vector<cmMakefile*>& locals = global->GetMakefiles();
   std::map<std::string, std::string> libDepsOld;
@@ -166,3 +140,20 @@
   }
   fout << "endif()\n";
 }
+
+bool cmExportLibraryDependenciesCommand::InitialPass(
+  std::vector<std::string> const& args, cmExecutionStatus&)
+{
+  if (args.empty()) {
+    this->SetError("called with incorrect number of arguments");
+    return false;
+  }
+
+  std::string const& filename = args[0];
+  bool const append = args.size() > 1 && args[1] == "APPEND";
+  this->Makefile->AddFinalAction([filename, append](cmMakefile& makefile) {
+    FinalAction(makefile, filename, append);
+  });
+
+  return true;
+}
diff --git a/Source/cmExportLibraryDependenciesCommand.h b/Source/cmExportLibraryDependenciesCommand.h
index 8414866..4817162 100644
--- a/Source/cmExportLibraryDependenciesCommand.h
+++ b/Source/cmExportLibraryDependenciesCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,20 +17,12 @@
 class cmExportLibraryDependenciesCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    return new cmExportLibraryDependenciesCommand;
+    return cm::make_unique<cmExportLibraryDependenciesCommand>();
   }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
-
-  void FinalPass() override;
-  bool HasFinalPass() const override { return true; }
-
-private:
-  std::string Filename;
-  bool Append = false;
-  void ConstFinalPass() const;
 };
 
 #endif
diff --git a/Source/cmFLTKWrapUICommand.cxx b/Source/cmFLTKWrapUICommand.cxx
index 89629c7..b7a2b27 100644
--- a/Source/cmFLTKWrapUICommand.cxx
+++ b/Source/cmFLTKWrapUICommand.cxx
@@ -13,6 +13,23 @@
 class cmExecutionStatus;
 class cmTarget;
 
+static void FinalAction(cmMakefile& makefile, std::string const& name)
+{
+  // people should add the srcs to the target themselves, but the old command
+  // didn't support that, so check and see if they added the files in and if
+  // they didn;t then print a warning and add then anyhow
+  cmTarget* target = makefile.FindLocalNonAliasTarget(name);
+  if (!target) {
+    std::string msg =
+      "FLTK_WRAP_UI was called with a target that was never created: ";
+    msg += name;
+    msg += ".  The problem was found while processing the source directory: ";
+    msg += makefile.GetCurrentSourceDirectory();
+    msg += ".  This FLTK_WRAP_UI call will be ignored.";
+    cmSystemTools::Message(msg, "Warning");
+  }
+}
+
 // cmFLTKWrapUICommand
 bool cmFLTKWrapUICommand::InitialPass(std::vector<std::string> const& args,
                                       cmExecutionStatus&)
@@ -27,8 +44,8 @@
   std::string const& fluid_exe =
     this->Makefile->GetRequiredDefinition("FLTK_FLUID_EXECUTABLE");
 
-  // get parameter for the command
-  this->Target = args[0]; // Target that will use the generated files
+  // Target that will use the generated files
+  std::string const& target = args[0];
 
   // get the list of GUI files from which .cxx and .h will be generated
   std::string outputDirectory = this->Makefile->GetCurrentBinaryDirectory();
@@ -41,6 +58,9 @@
     this->Makefile->AddIncludeDirectories(outputDirectories);
   }
 
+  // List of produced files.
+  std::vector<cmSourceFile*> generatedSourcesClasses;
+
   for (std::string const& arg : cmMakeRange(args).advance(1)) {
     cmSourceFile* curr = this->Makefile->GetSource(arg);
     // if we should use the source GUI
@@ -84,40 +104,24 @@
       cmSourceFile* sf = this->Makefile->GetSource(cxxres);
       sf->AddDepend(hname);
       sf->AddDepend(origname);
-      this->GeneratedSourcesClasses.push_back(sf);
+      generatedSourcesClasses.push_back(sf);
     }
   }
 
   // create the variable with the list of sources in it
-  size_t lastHeadersClass = this->GeneratedSourcesClasses.size();
+  size_t lastHeadersClass = generatedSourcesClasses.size();
   std::string sourceListValue;
   for (size_t classNum = 0; classNum < lastHeadersClass; classNum++) {
     if (classNum) {
       sourceListValue += ";";
     }
-    sourceListValue += this->GeneratedSourcesClasses[classNum]->GetFullPath();
+    sourceListValue += generatedSourcesClasses[classNum]->GetFullPath();
   }
-  std::string varName = this->Target;
-  varName += "_FLTK_UI_SRCS";
-  this->Makefile->AddDefinition(varName, sourceListValue.c_str());
 
+  std::string const varName = target + "_FLTK_UI_SRCS";
+  this->Makefile->AddDefinition(varName, sourceListValue);
+
+  this->Makefile->AddFinalAction(
+    [target](cmMakefile& makefile) { FinalAction(makefile, target); });
   return true;
 }
-
-void cmFLTKWrapUICommand::FinalPass()
-{
-  // people should add the srcs to the target themselves, but the old command
-  // didn't support that, so check and see if they added the files in and if
-  // they didn;t then print a warning and add then anyhow
-  cmTarget* target = this->Makefile->FindLocalNonAliasTarget(this->Target);
-  if (!target) {
-    std::string msg =
-      "FLTK_WRAP_UI was called with a target that was never created: ";
-    msg += this->Target;
-    msg += ".  The problem was found while processing the source directory: ";
-    msg += this->Makefile->GetCurrentSourceDirectory();
-    msg += ".  This FLTK_WRAP_UI call will be ignored.";
-    cmSystemTools::Message(msg, "Warning");
-    return;
-  }
-}
diff --git a/Source/cmFLTKWrapUICommand.h b/Source/cmFLTKWrapUICommand.h
index 044755e..ea8d401 100644
--- a/Source/cmFLTKWrapUICommand.h
+++ b/Source/cmFLTKWrapUICommand.h
@@ -8,10 +8,11 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
-class cmSourceFile;
 
 /** \class cmFLTKWrapUICommand
  * \brief Create .h and .cxx files rules for FLTK user interfaces files
@@ -25,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmFLTKWrapUICommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmFLTKWrapUICommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
@@ -33,27 +37,6 @@
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
-
-  /**
-   * This is called at the end after all the information
-   * specified by the command is accumulated. Most commands do
-   * not implement this method.  At this point, reading and
-   * writing to the cache can be done.
-   */
-  void FinalPass() override;
-  bool HasFinalPass() const override { return true; }
-
-private:
-  /**
-   * List of produced files.
-   */
-  std::vector<cmSourceFile*> GeneratedSourcesClasses;
-
-  /**
-   * List of Fluid files that provide the source
-   * generating .cxx and .h files
-   */
-  std::string Target;
 };
 
 #endif
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index 73b4123..7b916cd 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -1076,17 +1076,16 @@
   }
 
   // Add Windows-specific artifacts produced by the linker.
+  if (this->GT->HasImportLibrary(this->Config)) {
+    Json::Value artifact = Json::objectValue;
+    artifact["path"] =
+      RelativeIfUnder(this->TopBuild,
+                      this->GT->GetFullPath(
+                        this->Config, cmStateEnums::ImportLibraryArtifact));
+    artifacts.append(std::move(artifact)); // NOLINT(*)
+  }
   if (this->GT->IsDLLPlatform() &&
       this->GT->GetType() != cmStateEnums::STATIC_LIBRARY) {
-    if (this->GT->GetType() == cmStateEnums::SHARED_LIBRARY ||
-        this->GT->IsExecutableWithExports()) {
-      Json::Value artifact = Json::objectValue;
-      artifact["path"] =
-        RelativeIfUnder(this->TopBuild,
-                        this->GT->GetFullPath(
-                          this->Config, cmStateEnums::ImportLibraryArtifact));
-      artifacts.append(std::move(artifact)); // NOLINT(*)
-    }
     cmGeneratorTarget::OutputInfo const* output =
       this->GT->GetOutputInfo(this->Config);
     if (output && !output->PdbDir.empty()) {
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index dfba910..a8ee6a8 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -13,7 +13,6 @@
 #include <cmath>
 #include <ctype.h>
 #include <map>
-#include <memory>
 #include <set>
 #include <sstream>
 #include <stdio.h>
@@ -21,6 +20,8 @@
 #include <utility>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmArgumentParser.h"
 #include "cmCryptoHash.h"
@@ -364,7 +365,7 @@
       }
     }
   }
-  this->Makefile->AddDefinition(variable, output.c_str());
+  this->Makefile->AddDefinition(variable, output);
   return true;
 }
 
@@ -382,7 +383,7 @@
   if (hash) {
     std::string out = hash->HashFile(args[1]);
     if (!out.empty()) {
-      this->Makefile->AddDefinition(args[2], out.c_str());
+      this->Makefile->AddDefinition(args[2], out);
       return true;
     }
     std::ostringstream e;
@@ -750,7 +751,7 @@
   }
 
   // Save the output in a makefile variable.
-  this->Makefile->AddDefinition(outVar, output.c_str());
+  this->Makefile->AddDefinition(outVar, output);
   return true;
 }
 
@@ -937,7 +938,7 @@
 
   std::sort(files.begin(), files.end());
   files.erase(std::unique(files.begin(), files.end()), files.end());
-  this->Makefile->AddDefinition(variable, cmJoin(files, ";").c_str());
+  this->Makefile->AddDefinition(variable, cmJoin(files, ";"));
   return true;
 }
 
@@ -1070,6 +1071,7 @@
   std::string file;
   const char* oldRPath = nullptr;
   const char* newRPath = nullptr;
+  bool removeEnvironmentRPath = false;
   enum Doing
   {
     DoingNone,
@@ -1085,6 +1087,8 @@
       doing = DoingNew;
     } else if (args[i] == "FILE") {
       doing = DoingFile;
+    } else if (args[i] == "INSTALL_REMOVE_ENVIRONMENT_RPATH") {
+      removeEnvironmentRPath = true;
     } else if (doing == DoingFile) {
       file = args[i];
       doing = DoingNone;
@@ -1123,7 +1127,9 @@
   cmFileTimes const ft(file);
   std::string emsg;
   bool changed;
-  if (!cmSystemTools::ChangeRPath(file, oldRPath, newRPath, &emsg, &changed)) {
+
+  if (!cmSystemTools::ChangeRPath(file, oldRPath, newRPath,
+                                  removeEnvironmentRPath, &emsg, &changed)) {
     std::ostringstream e;
     /* clang-format off */
     e << "RPATH_CHANGE could not write new RPATH:\n"
@@ -1297,14 +1303,14 @@
     if (cmELF::StringEntry const* se_rpath = elf.GetRPath()) {
       std::string rpath(se_rpath->Value);
       std::replace(rpath.begin(), rpath.end(), ':', ';');
-      this->Makefile->AddDefinition(arguments.RPath, rpath.c_str());
+      this->Makefile->AddDefinition(arguments.RPath, rpath);
     }
   }
   if (!arguments.RunPath.empty()) {
     if (cmELF::StringEntry const* se_runpath = elf.GetRunPath()) {
       std::string runpath(se_runpath->Value);
       std::replace(runpath.begin(), runpath.end(), ':', ';');
-      this->Makefile->AddDefinition(arguments.RunPath, runpath.c_str());
+      this->Makefile->AddDefinition(arguments.RunPath, runpath);
     }
   }
 
@@ -1315,7 +1321,7 @@
     this->SetError(error);
     return false;
   }
-  this->Makefile->AddDefinition(arguments.Error, error.c_str());
+  this->Makefile->AddDefinition(arguments.Error, error);
   return true;
 #endif
 }
@@ -1353,7 +1359,7 @@
   }
 
   std::string res = cmSystemTools::RelativePath(directoryName, fileName);
-  this->Makefile->AddDefinition(outVar, res.c_str());
+  this->Makefile->AddDefinition(outVar, res);
   return true;
 }
 
@@ -1459,7 +1465,7 @@
 
   std::string value = cmJoin(
     cmMakeRange(path).transform(nativePath ? ToNativePath : ToCMakePath), ";");
-  this->Makefile->AddDefinition(args[2], value.c_str());
+  this->Makefile->AddDefinition(args[2], value);
   return true;
 }
 
@@ -1799,7 +1805,7 @@
       if (!statusVar.empty()) {
         std::ostringstream result;
         result << 0 << ";\"" << msg;
-        this->Makefile->AddDefinition(statusVar, result.str().c_str());
+        this->Makefile->AddDefinition(statusVar, result.str());
       }
       return true;
     }
@@ -1948,7 +1954,7 @@
     std::ostringstream result;
     result << static_cast<int>(res) << ";\"" << ::curl_easy_strerror(res)
            << "\"";
-    this->Makefile->AddDefinition(statusVar, result.str().c_str());
+    this->Makefile->AddDefinition(statusVar, result.str());
   }
 
   ::curl_global_cleanup();
@@ -1980,7 +1986,7 @@
         std::string status = "1;HASH mismatch: "
                              "expected: " +
           expectedHash + " actual: " + actualHash;
-        this->Makefile->AddDefinition(statusVar, status.c_str());
+        this->Makefile->AddDefinition(statusVar, status);
       }
 
       this->SetError(oss.str());
@@ -2235,7 +2241,7 @@
     std::ostringstream result;
     result << static_cast<int>(res) << ";\"" << ::curl_easy_strerror(res)
            << "\"";
-    this->Makefile->AddDefinition(statusVar, result.str().c_str());
+    this->Makefile->AddDefinition(statusVar, result.str());
   }
 
   ::curl_global_cleanup();
@@ -2260,7 +2266,7 @@
       log += "\n";
     }
 
-    this->Makefile->AddDefinition(logVar, log.c_str());
+    this->Makefile->AddDefinition(logVar, log);
   }
 
   return true;
@@ -2478,7 +2484,7 @@
   }
 
   if (!resultVariable.empty()) {
-    this->Makefile->AddDefinition(resultVariable, result.c_str());
+    this->Makefile->AddDefinition(resultVariable, result);
   }
 
   return true;
@@ -2527,7 +2533,7 @@
   cmTimestamp timestamp;
   std::string result =
     timestamp.FileModificationTime(filename.c_str(), formatString, utcFlag);
-  this->Makefile->AddDefinition(outputVariable, result.c_str());
+  this->Makefile->AddDefinition(outputVariable, result);
 
   return true;
 }
@@ -2555,8 +2561,7 @@
   }
 
   this->Makefile->AddDefinition(
-    outputVariable,
-    std::to_string(cmSystemTools::FileLength(filename)).c_str());
+    outputVariable, std::to_string(cmSystemTools::FileLength(filename)));
 
   return true;
 }
@@ -2583,7 +2588,7 @@
     return false;
   }
 
-  this->Makefile->AddDefinition(outputVariable, result.c_str());
+  this->Makefile->AddDefinition(outputVariable, result);
 
   return true;
 }
@@ -2629,7 +2634,7 @@
   if (fileName == newFileName) {
     result = "CREATE_LINK cannot use same file and newfile";
     if (!arguments.Result.empty()) {
-      this->Makefile->AddDefinition(arguments.Result, result.c_str());
+      this->Makefile->AddDefinition(arguments.Result, result);
       return true;
     }
     this->SetError(result);
@@ -2640,7 +2645,7 @@
   if (!arguments.Symbolic && !cmSystemTools::FileExists(fileName)) {
     result = "Cannot hard link \'" + fileName + "\' as it does not exist.";
     if (!arguments.Result.empty()) {
-      this->Makefile->AddDefinition(arguments.Result, result.c_str());
+      this->Makefile->AddDefinition(arguments.Result, result);
       return true;
     }
     this->SetError(result);
@@ -2657,7 +2662,7 @@
       << cmSystemTools::GetLastSystemError() << "\n";
 
     if (!arguments.Result.empty()) {
-      this->Makefile->AddDefinition(arguments.Result, e.str().c_str());
+      this->Makefile->AddDefinition(arguments.Result, e.str());
       return true;
     }
     this->SetError(e.str());
@@ -2692,7 +2697,7 @@
   }
 
   if (!arguments.Result.empty()) {
-    this->Makefile->AddDefinition(arguments.Result, result.c_str());
+    this->Makefile->AddDefinition(arguments.Result, result);
   }
 
   return true;
@@ -2820,7 +2825,7 @@
       std::string varName =
         parsedArgs.ConflictingDependenciesPrefix + "_" + val.first;
       std::string pathsStr = cmJoin(paths, ";");
-      this->Makefile->AddDefinition(varName, pathsStr.c_str());
+      this->Makefile->AddDefinition(varName, pathsStr);
     } else {
       std::ostringstream e;
       e << "Multiple conflicting paths found for " << val.first << ":";
@@ -2850,18 +2855,16 @@
 
   if (!parsedArgs.ResolvedDependenciesVar.empty()) {
     std::string val = cmJoin(deps, ";");
-    this->Makefile->AddDefinition(parsedArgs.ResolvedDependenciesVar,
-                                  val.c_str());
+    this->Makefile->AddDefinition(parsedArgs.ResolvedDependenciesVar, val);
   }
   if (!parsedArgs.UnresolvedDependenciesVar.empty()) {
     std::string val = cmJoin(unresolvedDeps, ";");
-    this->Makefile->AddDefinition(parsedArgs.UnresolvedDependenciesVar,
-                                  val.c_str());
+    this->Makefile->AddDefinition(parsedArgs.UnresolvedDependenciesVar, val);
   }
   if (!parsedArgs.ConflictingDependenciesPrefix.empty()) {
     std::string val = cmJoin(conflictingDeps, ";");
     this->Makefile->AddDefinition(
-      parsedArgs.ConflictingDependenciesPrefix + "_FILENAMES", val.c_str());
+      parsedArgs.ConflictingDependenciesPrefix + "_FILENAMES", val);
   }
   return true;
 }
diff --git a/Source/cmFileCommand.h b/Source/cmFileCommand.h
index cfff894..d4b980e 100644
--- a/Source/cmFileCommand.h
+++ b/Source/cmFileCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -22,7 +24,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmFileCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmFileCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmFileCopier.cxx b/Source/cmFileCopier.cxx
index 49e8cd5..4f1a158 100644
--- a/Source/cmFileCopier.cxx
+++ b/Source/cmFileCopier.cxx
@@ -174,11 +174,8 @@
     cmSystemTools::ExpandListArgument(default_dir_install_permissions, items);
     for (const auto& arg : items) {
       if (!this->CheckPermissions(arg, **mode)) {
-        std::ostringstream e;
-        e << this->FileCommand->GetError()
-          << " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS "
-             "variable.";
-        this->FileCommand->SetError(e.str());
+        this->FileCommand->SetError(
+          " Set with CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS variable.");
         return false;
       }
     }
diff --git a/Source/cmFileInstaller.cxx b/Source/cmFileInstaller.cxx
index d4f76fd..9378439 100644
--- a/Source/cmFileInstaller.cxx
+++ b/Source/cmFileInstaller.cxx
@@ -38,7 +38,7 @@
 {
   // Save the updated install manifest.
   this->Makefile->AddDefinition("CMAKE_INSTALL_MANIFEST_FILES",
-                                this->Manifest.c_str());
+                                this->Manifest);
 }
 
 void cmFileInstaller::ManifestAppend(std::string const& file)
diff --git a/Source/cmFileTimes.cxx b/Source/cmFileTimes.cxx
index fd4f679..3824e9b 100644
--- a/Source/cmFileTimes.cxx
+++ b/Source/cmFileTimes.cxx
@@ -2,11 +2,12 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmFileTimes.h"
 
-#include "cmAlgorithms.h"
 #include "cm_sys_stat.h"
 
 #include <utility>
 
+#include "cm_memory.hxx"
+
 #if defined(_WIN32)
 #  include "cmSystemTools.h"
 #  include <windows.h>
diff --git a/Source/cmFindFileCommand.h b/Source/cmFindFileCommand.h
index 4309449..152b505 100644
--- a/Source/cmFindFileCommand.h
+++ b/Source/cmFindFileCommand.h
@@ -5,9 +5,10 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include "cmFindPathCommand.h"
+#include "cm_memory.hxx"
 
-class cmCommand;
+#include "cmCommand.h"
+#include "cmFindPathCommand.h"
 
 /** \class cmFindFileCommand
  * \brief Define a command to search for an executable program.
@@ -24,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmFindFileCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmFindFileCommand>();
+  }
 };
 
 #endif
diff --git a/Source/cmFindLibraryCommand.h b/Source/cmFindLibraryCommand.h
index fb8a700..af17d60 100644
--- a/Source/cmFindLibraryCommand.h
+++ b/Source/cmFindLibraryCommand.h
@@ -8,9 +8,11 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
 #include "cmFindBase.h"
 
-class cmCommand;
 class cmExecutionStatus;
 
 /** \class cmFindLibraryCommand
@@ -27,7 +29,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmFindLibraryCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmFindLibraryCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 783b5f6..db3f4ef 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -13,12 +13,13 @@
 #include <deque>
 #include <functional>
 #include <iterator>
-#include <memory>
 #include <sstream>
 #include <stdio.h>
 #include <string.h>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
@@ -224,6 +225,9 @@
     this->SortDirection = strcmp(sd, "ASC") == 0 ? Asc : Dec;
   }
 
+  // Find what search path locations have been enabled/disable
+  this->SelectDefaultSearchModes();
+
   // Find the current root path mode.
   this->SelectDefaultRootPathMode();
 
@@ -674,7 +678,9 @@
   } else {
     this->OriginalDefs[var].exists = false;
   }
-  this->Makefile->AddDefinition(var, val);
+  if (val) {
+    this->Makefile->AddDefinition(var, val);
+  }
 }
 
 void cmFindPackageCommand::RestoreFindDefinitions()
@@ -682,7 +688,7 @@
   for (auto const& i : this->OriginalDefs) {
     OriginalDef const& od = i.second;
     if (od.exists) {
-      this->Makefile->AddDefinition(i.first, od.value.c_str());
+      this->Makefile->AddDefinition(i.first, od.value);
     } else {
       this->Makefile->RemoveDefinition(i.first);
     }
@@ -822,8 +828,9 @@
     }
   }
 
-  if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_PREFER_CONFIG") && !found &&
-      handlePackageModeType == HandlePackageModeType::Config) {
+  if (this->UseFindModules && !found &&
+      handlePackageModeType == HandlePackageModeType::Config &&
+      this->Makefile->IsOn("CMAKE_FIND_PACKAGE_PREFER_CONFIG")) {
     // Config mode failed. Allow Module case.
     result = false;
   }
@@ -955,7 +962,7 @@
   std::string fileVar = this->Name;
   fileVar += "_CONFIG";
   if (found) {
-    this->Makefile->AddDefinition(fileVar, this->FileFound.c_str());
+    this->Makefile->AddDefinition(fileVar, this->FileFound);
   } else {
     this->Makefile->RemoveDefinition(fileVar);
   }
@@ -977,11 +984,9 @@
     sep = ";";
   }
 
-  this->Makefile->AddDefinition(consideredConfigsVar,
-                                consideredConfigFiles.c_str());
+  this->Makefile->AddDefinition(consideredConfigsVar, consideredConfigFiles);
 
-  this->Makefile->AddDefinition(consideredVersionsVar,
-                                consideredVersions.c_str());
+  this->Makefile->AddDefinition(consideredVersionsVar, consideredVersions);
 
   return result;
 }
@@ -1610,8 +1615,8 @@
   this->Makefile->RemoveDefinition("PACKAGE_VERSION_EXACT");
 
   // Set the input variables.
-  this->Makefile->AddDefinition("PACKAGE_FIND_NAME", this->Name.c_str());
-  this->Makefile->AddDefinition("PACKAGE_FIND_VERSION", this->Version.c_str());
+  this->Makefile->AddDefinition("PACKAGE_FIND_NAME", this->Name);
+  this->Makefile->AddDefinition("PACKAGE_FIND_VERSION", this->Version);
   char buf[64];
   sprintf(buf, "%u", this->VersionMajor);
   this->Makefile->AddDefinition("PACKAGE_FIND_VERSION_MAJOR", buf);
@@ -1688,7 +1693,7 @@
   if (this->VersionFound.empty()) {
     this->Makefile->RemoveDefinition(ver);
   } else {
-    this->Makefile->AddDefinition(ver, this->VersionFound.c_str());
+    this->Makefile->AddDefinition(ver, this->VersionFound);
   }
 
   // Store the version components.
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 316ca0f..f6645ae 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -3,6 +3,7 @@
 #ifndef cmFindPackageCommand_h
 #define cmFindPackageCommand_h
 
+#include "cmCommand.h"
 #include "cmConfigure.h" // IWYU pragma: keep
 #include "cmPolicies.h"
 
@@ -14,6 +15,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 // IWYU insists we should forward-declare instead of including <functional>,
 // but we cannot forward-declare reliably because some C++ standard libraries
 // put the template in an inline namespace.
@@ -27,7 +30,6 @@
 
 #include "cmFindCommon.h"
 
-class cmCommand;
 class cmExecutionStatus;
 class cmSearchPath;
 
@@ -65,7 +67,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmFindPackageCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmFindPackageCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmFindPathCommand.h b/Source/cmFindPathCommand.h
index cb0db4c..89e2cef 100644
--- a/Source/cmFindPathCommand.h
+++ b/Source/cmFindPathCommand.h
@@ -8,9 +8,11 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
 #include "cmFindBase.h"
 
-class cmCommand;
 class cmExecutionStatus;
 
 /** \class cmFindPathCommand
@@ -27,7 +29,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmFindPathCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmFindPathCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmFindProgramCommand.h b/Source/cmFindProgramCommand.h
index 147936c..40e455e 100644
--- a/Source/cmFindProgramCommand.h
+++ b/Source/cmFindProgramCommand.h
@@ -8,9 +8,11 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
 #include "cmFindBase.h"
 
-class cmCommand;
 class cmExecutionStatus;
 
 /** \class cmFindProgramCommand
@@ -28,7 +30,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmFindProgramCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmFindProgramCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index 7f189d6..06dce2c 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -2,12 +2,13 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmForEachCommand.h"
 
-#include <memory>
 #include <sstream>
 #include <stdio.h>
 #include <stdlib.h>
+#include <utility>
 
-#include "cmAlgorithms.h"
+#include "cm_memory.hxx"
+
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
 #include "cmMessageType.h"
@@ -52,21 +53,21 @@
 
       for (std::string const& arg : cmMakeRange(this->Args).advance(1)) {
         // set the variable to the loop value
-        mf.AddDefinition(this->Args[0], arg.c_str());
+        mf.AddDefinition(this->Args[0], arg);
         // Invoke all the functions that were collected in the block.
-        cmExecutionStatus status;
+        cmExecutionStatus status(mf);
         for (cmListFileFunction const& func : this->Functions) {
           status.Clear();
           mf.ExecuteCommand(func, status);
           if (status.GetReturnInvoked()) {
             inStatus.SetReturnInvoked();
             // restore the variable to its prior value
-            mf.AddDefinition(this->Args[0], oldDef.c_str());
+            mf.AddDefinition(this->Args[0], oldDef);
             return true;
           }
           if (status.GetBreakInvoked()) {
             // restore the variable to its prior value
-            mf.AddDefinition(this->Args[0], oldDef.c_str());
+            mf.AddDefinition(this->Args[0], oldDef);
             return true;
           }
           if (status.GetContinueInvoked()) {
@@ -79,7 +80,7 @@
       }
 
       // restore the variable to its prior value
-      mf.AddDefinition(this->Args[0], oldDef.c_str());
+      mf.AddDefinition(this->Args[0], oldDef);
       return true;
     }
     // close out a nested foreach
@@ -121,7 +122,7 @@
   }
 
   // create a function blocker
-  auto f = cm::make_unique<cmForEachFunctionBlocker>(this->Makefile);
+  auto fb = cm::make_unique<cmForEachFunctionBlocker>(this->Makefile);
   if (args.size() > 1) {
     if (args[1] == "RANGE") {
       int start = 0;
@@ -168,23 +169,22 @@
           break;
         }
       }
-      f->Args = range;
+      fb->Args = range;
     } else {
-      f->Args = args;
+      fb->Args = args;
     }
   } else {
-    f->Args = args;
+    fb->Args = args;
   }
-  this->Makefile->AddFunctionBlocker(f.release());
+  this->Makefile->AddFunctionBlocker(std::move(fb));
 
   return true;
 }
 
 bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args)
 {
-  std::unique_ptr<cmForEachFunctionBlocker> f(
-    new cmForEachFunctionBlocker(this->Makefile));
-  f->Args.push_back(args[0]);
+  auto fb = cm::make_unique<cmForEachFunctionBlocker>(this->Makefile);
+  fb->Args.push_back(args[0]);
 
   enum Doing
   {
@@ -195,7 +195,7 @@
   Doing doing = DoingNone;
   for (unsigned int i = 2; i < args.size(); ++i) {
     if (doing == DoingItems) {
-      f->Args.push_back(args[i]);
+      fb->Args.push_back(args[i]);
     } else if (args[i] == "LISTS") {
       doing = DoingLists;
     } else if (args[i] == "ITEMS") {
@@ -203,7 +203,7 @@
     } else if (doing == DoingLists) {
       const char* value = this->Makefile->GetDefinition(args[i]);
       if (value && *value) {
-        cmSystemTools::ExpandListArgument(value, f->Args, true);
+        cmSystemTools::ExpandListArgument(value, fb->Args, true);
       }
     } else {
       std::ostringstream e;
@@ -214,7 +214,7 @@
     }
   }
 
-  this->Makefile->AddFunctionBlocker(f.release()); // TODO: pass unique_ptr
+  this->Makefile->AddFunctionBlocker(std::move(fb));
 
   return true;
 }
diff --git a/Source/cmForEachCommand.h b/Source/cmForEachCommand.h
index 5131a4f..cd112b8 100644
--- a/Source/cmForEachCommand.h
+++ b/Source/cmForEachCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 #include "cmFunctionBlocker.h"
 #include "cmListFileCache.h"
@@ -39,7 +41,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmForEachCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmForEachCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 9067a5f..6afd31a 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -3,6 +3,7 @@
 #include "cmFunctionCommand.h"
 
 #include <sstream>
+#include <utility>
 
 #include "cmAlgorithms.h"
 #include "cmExecutionStatus.h"
@@ -12,35 +13,15 @@
 #include "cmState.h"
 
 // define the class for function commands
-class cmFunctionHelperCommand : public cmCommand
+class cmFunctionHelperCommand
 {
 public:
   /**
-   * This is a virtual constructor for the command.
-   */
-  cmCommand* Clone() override
-  {
-    cmFunctionHelperCommand* newC = new cmFunctionHelperCommand;
-    // we must copy when we clone
-    newC->Args = this->Args;
-    newC->Functions = this->Functions;
-    newC->Policies = this->Policies;
-    newC->FilePath = this->FilePath;
-    return newC;
-  }
-
-  /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
-  bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
-                         cmExecutionStatus&) override;
-
-  bool InitialPass(std::vector<std::string> const&,
-                   cmExecutionStatus&) override
-  {
-    return false;
-  }
+  bool operator()(std::vector<cmListFileArgument> const& args,
+                  cmExecutionStatus& inStatus) const;
 
   std::vector<std::string> Args;
   std::vector<cmListFileFunction> Functions;
@@ -48,12 +29,15 @@
   std::string FilePath;
 };
 
-bool cmFunctionHelperCommand::InvokeInitialPass(
-  const std::vector<cmListFileArgument>& args, cmExecutionStatus& inStatus)
+bool cmFunctionHelperCommand::operator()(
+  std::vector<cmListFileArgument> const& args,
+  cmExecutionStatus& inStatus) const
 {
+  cmMakefile& makefile = inStatus.GetMakefile();
+
   // Expand the argument list to the function.
   std::vector<std::string> expandedArgs;
-  this->Makefile->ExpandArguments(args, expandedArgs);
+  makefile.ExpandArguments(args, expandedArgs);
 
   // make sure the number of arguments passed is at least the number
   // required by the signature
@@ -61,30 +45,30 @@
     std::string errorMsg =
       "Function invoked with incorrect arguments for function named: ";
     errorMsg += this->Args[0];
-    this->SetError(errorMsg);
+    inStatus.SetError(errorMsg);
     return false;
   }
 
-  cmMakefile::FunctionPushPop functionScope(this->Makefile, this->FilePath,
+  cmMakefile::FunctionPushPop functionScope(&makefile, this->FilePath,
                                             this->Policies);
 
   // set the value of argc
   std::ostringstream strStream;
   strStream << expandedArgs.size();
-  this->Makefile->AddDefinition("ARGC", strStream.str().c_str());
-  this->Makefile->MarkVariableAsUsed("ARGC");
+  makefile.AddDefinition("ARGC", strStream.str());
+  makefile.MarkVariableAsUsed("ARGC");
 
   // set the values for ARGV0 ARGV1 ...
   for (unsigned int t = 0; t < expandedArgs.size(); ++t) {
     std::ostringstream tmpStream;
     tmpStream << "ARGV" << t;
-    this->Makefile->AddDefinition(tmpStream.str(), expandedArgs[t].c_str());
-    this->Makefile->MarkVariableAsUsed(tmpStream.str());
+    makefile.AddDefinition(tmpStream.str(), expandedArgs[t]);
+    makefile.MarkVariableAsUsed(tmpStream.str());
   }
 
   // define the formal arguments
   for (unsigned int j = 1; j < this->Args.size(); ++j) {
-    this->Makefile->AddDefinition(this->Args[j], expandedArgs[j - 1].c_str());
+    makefile.AddDefinition(this->Args[j], expandedArgs[j - 1]);
   }
 
   // define ARGV and ARGN
@@ -92,17 +76,16 @@
   std::vector<std::string>::const_iterator eit =
     expandedArgs.begin() + (this->Args.size() - 1);
   std::string argnDef = cmJoin(cmMakeRange(eit, expandedArgs.end()), ";");
-  this->Makefile->AddDefinition("ARGV", argvDef.c_str());
-  this->Makefile->MarkVariableAsUsed("ARGV");
-  this->Makefile->AddDefinition("ARGN", argnDef.c_str());
-  this->Makefile->MarkVariableAsUsed("ARGN");
+  makefile.AddDefinition("ARGV", argvDef);
+  makefile.MarkVariableAsUsed("ARGV");
+  makefile.AddDefinition("ARGN", argnDef);
+  makefile.MarkVariableAsUsed("ARGN");
 
   // Invoke all the functions that were collected in the block.
   // for each function
   for (cmListFileFunction const& func : this->Functions) {
-    cmExecutionStatus status;
-    if (!this->Makefile->ExecuteCommand(func, status) ||
-        status.GetNestedError()) {
+    cmExecutionStatus status(makefile);
+    if (!makefile.ExecuteCommand(func, status) || status.GetNestedError()) {
       // The error message should have already included the call stack
       // so we do not need to report an error here.
       functionScope.Quiet();
@@ -129,12 +112,12 @@
     // if this is the endfunction for this function then execute
     if (!this->Depth) {
       // create a new command and add it to cmake
-      cmFunctionHelperCommand* f = new cmFunctionHelperCommand();
-      f->Args = this->Args;
-      f->Functions = this->Functions;
-      f->FilePath = this->GetStartingContext().FilePath;
-      mf.RecordPolicies(f->Policies);
-      mf.GetState()->AddScriptedCommand(this->Args[0], f);
+      cmFunctionHelperCommand f;
+      f.Args = this->Args;
+      f.Functions = this->Functions;
+      f.FilePath = this->GetStartingContext().FilePath;
+      mf.RecordPolicies(f.Policies);
+      mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
       // remove the function blocker now that the function is defined
       mf.RemoveFunctionBlocker(this, lff);
       return true;
@@ -176,8 +159,10 @@
   }
 
   // create a function blocker
-  cmFunctionFunctionBlocker* f = new cmFunctionFunctionBlocker();
-  cmAppend(f->Args, args);
-  this->Makefile->AddFunctionBlocker(f);
+  {
+    auto fb = cm::make_unique<cmFunctionFunctionBlocker>();
+    cmAppend(fb->Args, args);
+    this->Makefile->AddFunctionBlocker(std::move(fb));
+  }
   return true;
 }
diff --git a/Source/cmFunctionCommand.h b/Source/cmFunctionCommand.h
index 8b37df0..449a180 100644
--- a/Source/cmFunctionCommand.h
+++ b/Source/cmFunctionCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 #include "cmFunctionBlocker.h"
 #include "cmListFileCache.h"
@@ -34,7 +36,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmFunctionCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmFunctionCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 728f2a4..817f41e 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -68,9 +68,7 @@
         return;
       }
     }
-    const_cast<cmGeneratorExpressionDAGChecker*>(top)
-      ->Seen[this->Target]
-      .insert(this->Property);
+    top->Seen[this->Target].insert(this->Property);
   }
 }
 
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index e1fba5e..6d7d6ef 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -88,7 +88,7 @@
   const cmGeneratorExpressionDAGChecker* const Parent;
   cmGeneratorTarget const* Target;
   const std::string Property;
-  std::map<cmGeneratorTarget const*, std::set<std::string>> Seen;
+  mutable std::map<cmGeneratorTarget const*, std::set<std::string>> Seen;
   const GeneratorExpressionContent* const Content;
   const cmListFileBacktrace Backtrace;
   Result CheckResult;
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index d828dac..49d0c47 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1038,45 +1038,38 @@
   }
 } languageAndIdNode;
 
-#define TRANSITIVE_PROPERTY_NAME(PROPERTY) , "INTERFACE_" #PROPERTY
-
-static const char* targetPropertyTransitiveWhitelist[] = {
-  nullptr CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(TRANSITIVE_PROPERTY_NAME)
-};
-
-#undef TRANSITIVE_PROPERTY_NAME
-
-template <typename T>
 std::string getLinkedTargetsContent(
-  std::vector<T> const& libraries, cmGeneratorTarget const* target,
-  cmGeneratorTarget const* headTarget, cmGeneratorExpressionContext* context,
-  cmGeneratorExpressionDAGChecker* dagChecker,
-  const std::string& interfacePropertyName)
+  cmGeneratorTarget const* target, std::string const& prop,
+  cmGeneratorExpressionContext* context,
+  cmGeneratorExpressionDAGChecker* dagChecker)
 {
-  std::string linkedTargetsContent;
-  std::string sep;
-  std::string depString;
-  for (T const& l : libraries) {
-    // Broken code can have a target in its own link interface.
-    // Don't follow such link interface entries so as not to create a
-    // self-referencing loop.
-    if (l.Target && l.Target != target) {
-      std::string uniqueName =
-        target->GetGlobalGenerator()->IndexGeneratorTargetUniquely(l.Target);
-      depString += sep + "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," +
-        interfacePropertyName + ">";
-      sep = ";";
+  std::string result;
+  if (cmLinkImplementationLibraries const* impl =
+        target->GetLinkImplementationLibraries(context->Config)) {
+    for (cmLinkImplItem const& lib : impl->Libraries) {
+      if (lib.Target) {
+        // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
+        // caller's property and hand-evaluate it as if it were compiled.
+        // Create a context as cmCompiledGeneratorExpression::Evaluate does.
+        cmGeneratorExpressionContext libContext(
+          target->GetLocalGenerator(), context->Config, context->Quiet, target,
+          target, context->EvaluateForBuildsystem, lib.Backtrace,
+          context->Language);
+        std::string libResult =
+          lib.Target->EvaluateInterfaceProperty(prop, &libContext, dagChecker);
+        if (!libResult.empty()) {
+          if (result.empty()) {
+            result = std::move(libResult);
+          } else {
+            result.reserve(result.size() + 1 + libResult.size());
+            result += ";";
+            result += libResult;
+          }
+        }
+      }
     }
   }
-  if (!depString.empty()) {
-    linkedTargetsContent =
-      cmGeneratorExpressionNode::EvaluateDependentExpression(
-        depString, target->GetLocalGenerator(), context, headTarget, target,
-        dagChecker);
-  }
-  linkedTargetsContent =
-    cmGeneratorExpression::StripEmptyListElements(linkedTargetsContent);
-  return linkedTargetsContent;
+  return result;
 }
 
 static const struct TargetPropertyNode : public cmGeneratorExpressionNode
@@ -1205,67 +1198,6 @@
       return target->GetLinkerLanguage(context->Config);
     }
 
-    cmGeneratorExpressionDAGChecker dagChecker(
-      context->Backtrace, target, propertyName, content, dagCheckerParent);
-
-    switch (dagChecker.Check()) {
-      case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
-        dagChecker.ReportError(context, content->GetOriginalExpression());
-        return std::string();
-      case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
-        // No error. We just skip cyclic references.
-        return std::string();
-      case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
-        for (size_t i = 1; i < cm::size(targetPropertyTransitiveWhitelist);
-             ++i) {
-          if (targetPropertyTransitiveWhitelist[i] == propertyName) {
-            // No error. We're not going to find anything new here.
-            return std::string();
-          }
-        }
-      case cmGeneratorExpressionDAGChecker::DAG:
-        break;
-    }
-
-    std::string prop;
-    bool haveProp = false;
-    if (const char* p = target->GetProperty(propertyName)) {
-      prop = p;
-      haveProp = true;
-    }
-
-    if (dagCheckerParent) {
-      if (dagCheckerParent->EvaluatingGenexExpression() ||
-          dagCheckerParent->EvaluatingPICExpression()) {
-        // No check required.
-      } else if (dagCheckerParent->EvaluatingLinkLibraries()) {
-#define TRANSITIVE_PROPERTY_COMPARE(PROPERTY)                                 \
-  (#PROPERTY == propertyName || "INTERFACE_" #PROPERTY == propertyName) ||
-        if (CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME(
-              TRANSITIVE_PROPERTY_COMPARE) false) { // NOLINT(*)
-          reportError(
-            context, content->GetOriginalExpression(),
-            "$<TARGET_PROPERTY:...> expression in link libraries "
-            "evaluation depends on target property which is transitive "
-            "over the link libraries, creating a recursion.");
-          return std::string();
-        }
-#undef TRANSITIVE_PROPERTY_COMPARE
-
-        if (!haveProp) {
-          return std::string();
-        }
-      } else {
-#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) dagCheckerParent->METHOD() ||
-
-        assert(CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
-          ASSERT_TRANSITIVE_PROPERTY_METHOD) false); // NOLINT(clang-tidy)
-#undef ASSERT_TRANSITIVE_PROPERTY_METHOD
-      }
-    }
-
-    std::string linkedTargetsContent;
-
     std::string interfacePropertyName;
     bool isInterfaceProperty = false;
 
@@ -1287,32 +1219,64 @@
       }
     }
 #undef POPULATE_INTERFACE_PROPERTY_NAME
-    cmGeneratorTarget const* headTarget =
-      context->HeadTarget && isInterfaceProperty ? context->HeadTarget
-                                                 : target;
 
-    if (isInterfaceProperty) {
-      if (cmLinkInterfaceLibraries const* iface =
-            target->GetLinkInterfaceLibraries(context->Config, headTarget,
-                                              true)) {
-        linkedTargetsContent =
-          getLinkedTargetsContent(iface->Libraries, target, headTarget,
-                                  context, &dagChecker, interfacePropertyName);
-      }
-    } else if (!interfacePropertyName.empty()) {
-      if (cmLinkImplementationLibraries const* impl =
-            target->GetLinkImplementationLibraries(context->Config)) {
-        linkedTargetsContent =
-          getLinkedTargetsContent(impl->Libraries, target, target, context,
-                                  &dagChecker, interfacePropertyName);
+    bool evaluatingLinkLibraries = false;
+
+    if (dagCheckerParent) {
+      if (dagCheckerParent->EvaluatingGenexExpression() ||
+          dagCheckerParent->EvaluatingPICExpression()) {
+        // No check required.
+      } else if (dagCheckerParent->EvaluatingLinkLibraries()) {
+        evaluatingLinkLibraries = true;
+        if (!interfacePropertyName.empty()) {
+          reportError(
+            context, content->GetOriginalExpression(),
+            "$<TARGET_PROPERTY:...> expression in link libraries "
+            "evaluation depends on target property which is transitive "
+            "over the link libraries, creating a recursion.");
+          return std::string();
+        }
+      } else {
+#define ASSERT_TRANSITIVE_PROPERTY_METHOD(METHOD) dagCheckerParent->METHOD() ||
+        assert(CM_FOR_EACH_TRANSITIVE_PROPERTY_METHOD(
+          ASSERT_TRANSITIVE_PROPERTY_METHOD) false); // NOLINT(clang-tidy)
+#undef ASSERT_TRANSITIVE_PROPERTY_METHOD
       }
     }
 
-    if (!haveProp) {
-      if (target->IsImported() ||
-          target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
-        return linkedTargetsContent;
-      }
+    if (isInterfaceProperty) {
+      return target->EvaluateInterfaceProperty(propertyName, context,
+                                               dagCheckerParent);
+    }
+
+    cmGeneratorExpressionDAGChecker dagChecker(
+      context->Backtrace, target, propertyName, content, dagCheckerParent);
+
+    switch (dagChecker.Check()) {
+      case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+        dagChecker.ReportError(context, content->GetOriginalExpression());
+        return std::string();
+      case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+        // No error. We just skip cyclic references.
+        return std::string();
+      case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+        // We handle transitive properties above.  For non-transitive
+        // properties we accept repeats anyway.
+      case cmGeneratorExpressionDAGChecker::DAG:
+        break;
+    }
+
+    std::string result;
+    bool haveProp = false;
+    if (const char* p = target->GetProperty(propertyName)) {
+      result = p;
+      haveProp = true;
+    } else if (evaluatingLinkLibraries) {
+      return std::string();
+    }
+
+    if (!haveProp && !target->IsImported() &&
+        target->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
       if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
                                                        context->Config)) {
         context->HadContextSensitiveCondition = true;
@@ -1345,8 +1309,6 @@
                                                              context->Config);
         return propContent ? propContent : "";
       }
-
-      return linkedTargetsContent;
     }
 
     if (!target->IsImported() && dagCheckerParent &&
@@ -1368,15 +1330,17 @@
         return propContent ? propContent : "";
       }
     }
+
     if (!interfacePropertyName.empty()) {
-      std::string result = this->EvaluateDependentExpression(
-        prop, context->LG, context, headTarget, target, &dagChecker);
+      result = this->EvaluateDependentExpression(result, context->LG, context,
+                                                 target, target, &dagChecker);
+      std::string linkedTargetsContent = getLinkedTargetsContent(
+        target, interfacePropertyName, context, &dagChecker);
       if (!linkedTargetsContent.empty()) {
         result += (result.empty() ? "" : ";") + linkedTargetsContent;
       }
-      return result;
     }
-    return prop;
+    return result;
   }
 } targetPropertyNode;
 
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 845937a..7c41045 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -22,7 +22,9 @@
 #include "cmCustomCommandGenerator.h"
 #include "cmCustomCommandLines.h"
 #include "cmGeneratorExpression.h"
+#include "cmGeneratorExpressionContext.h"
 #include "cmGeneratorExpressionDAGChecker.h"
+#include "cmGeneratorExpressionNode.h"
 #include "cmGlobalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
@@ -92,9 +94,6 @@
   virtual bool GetHadContextSensitiveCondition() const { return false; }
 
   cmLinkImplItem const& LinkImplItem;
-
-private:
-  cmListFileBacktrace Backtrace;
 };
 cmLinkImplItem cmGeneratorTarget::TargetPropertyEntry::NoLinkImplItem;
 
@@ -209,6 +208,63 @@
   }
 }
 
+namespace {
+// Represent a target property entry after evaluating generator expressions
+// and splitting up lists.
+struct EvaluatedTargetPropertyEntry
+{
+  EvaluatedTargetPropertyEntry(cmLinkImplItem const& item,
+                               cmListFileBacktrace bt)
+    : LinkImplItem(item)
+    , Backtrace(std::move(bt))
+  {
+  }
+
+  // Move-only.
+  EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry&&) = default;
+  EvaluatedTargetPropertyEntry(EvaluatedTargetPropertyEntry const&) = delete;
+  EvaluatedTargetPropertyEntry& operator=(EvaluatedTargetPropertyEntry&&) =
+    delete;
+  EvaluatedTargetPropertyEntry& operator=(
+    EvaluatedTargetPropertyEntry const&) = delete;
+
+  cmLinkImplItem const& LinkImplItem;
+  cmListFileBacktrace Backtrace;
+  std::vector<std::string> Values;
+  bool ContextDependent = false;
+};
+
+EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
+  cmGeneratorTarget const* thisTarget, std::string const& config,
+  std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
+  cmGeneratorTarget::TargetPropertyEntry* entry)
+{
+  EvaluatedTargetPropertyEntry ee(entry->LinkImplItem, entry->GetBacktrace());
+  cmSystemTools::ExpandListArgument(
+    entry->Evaluate(thisTarget->GetLocalGenerator(), config, false, thisTarget,
+                    dagChecker, lang),
+    ee.Values);
+  if (entry->GetHadContextSensitiveCondition()) {
+    ee.ContextDependent = true;
+  }
+  return ee;
+}
+
+std::vector<EvaluatedTargetPropertyEntry> EvaluateTargetPropertyEntries(
+  cmGeneratorTarget const* thisTarget, std::string const& config,
+  std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
+  std::vector<cmGeneratorTarget::TargetPropertyEntry*> const& in)
+{
+  std::vector<EvaluatedTargetPropertyEntry> out;
+  out.reserve(in.size());
+  for (cmGeneratorTarget::TargetPropertyEntry* entry : in) {
+    out.emplace_back(EvaluateTargetPropertyEntry(thisTarget, config, lang,
+                                                 dagChecker, entry));
+  }
+  return out;
+}
+}
+
 cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
   : Target(t)
   , FortranModuleDirectoryCreated(false)
@@ -259,9 +315,6 @@
                                      t->GetSourceBacktraces(),
                                      this->SourceEntries, true);
 
-  this->DLLPlatform =
-    !this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty();
-
   this->PolicyMap = t->GetPolicyMap();
 }
 
@@ -468,7 +521,7 @@
   const std::string& config, cmStateEnums::ArtifactType artifact) const
 {
   if (this->IsImported()) {
-    const char* prefix = this->GetFilePrefixInternal(artifact);
+    const char* prefix = this->GetFilePrefixInternal(config, artifact);
 
     return prefix ? prefix : std::string();
   }
@@ -481,7 +534,7 @@
   const std::string& config, cmStateEnums::ArtifactType artifact) const
 {
   if (this->IsImported()) {
-    const char* suffix = this->GetFileSuffixInternal(artifact);
+    const char* suffix = this->GetFileSuffixInternal(config, artifact);
 
     return suffix ? suffix : std::string();
   }
@@ -508,7 +561,8 @@
 }
 
 const char* cmGeneratorTarget::GetFilePrefixInternal(
-  cmStateEnums::ArtifactType artifact, const std::string& language) const
+  std::string const& config, cmStateEnums::ArtifactType artifact,
+  const std::string& language) const
 {
   // no prefix for non-main target types.
   if (this->GetType() != cmStateEnums::STATIC_LIBRARY &&
@@ -523,8 +577,7 @@
 
   // Return an empty prefix for the import library if this platform
   // does not support import libraries.
-  if (isImportedLibraryArtifact &&
-      !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+  if (isImportedLibraryArtifact && !this->NeedImportLibraryName(config)) {
     return nullptr;
   }
 
@@ -558,7 +611,8 @@
   return targetPrefix;
 }
 const char* cmGeneratorTarget::GetFileSuffixInternal(
-  cmStateEnums::ArtifactType artifact, const std::string& language) const
+  std::string const& config, cmStateEnums::ArtifactType artifact,
+  const std::string& language) const
 {
   // no suffix for non-main target types.
   if (this->GetType() != cmStateEnums::STATIC_LIBRARY &&
@@ -573,8 +627,7 @@
 
   // Return an empty suffix for the import library if this platform
   // does not support import libraries.
-  if (isImportedLibraryArtifact &&
-      !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+  if (isImportedLibraryArtifact && !this->NeedImportLibraryName(config)) {
     return nullptr;
   }
 
@@ -657,12 +710,14 @@
   return nullptr;
 }
 
-static void handleSystemIncludesDep(
-  cmLocalGenerator* lg, cmGeneratorTarget const* depTgt,
-  const std::string& config, cmGeneratorTarget const* headTarget,
-  cmGeneratorExpressionDAGChecker* dagChecker,
-  std::vector<std::string>& result, bool excludeImported,
-  std::string const& language)
+namespace {
+void handleSystemIncludesDep(cmLocalGenerator* lg,
+                             cmGeneratorTarget const* depTgt,
+                             const std::string& config,
+                             cmGeneratorTarget const* headTarget,
+                             cmGeneratorExpressionDAGChecker* dagChecker,
+                             std::vector<std::string>& result,
+                             bool excludeImported, std::string const& language)
 {
   if (const char* dirs =
         depTgt->GetProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES")) {
@@ -685,6 +740,7 @@
       result);
   }
 }
+}
 
 /* clang-format off */
 #define IMPLEMENT_VISIT(KIND)                                                 \
@@ -1087,77 +1143,205 @@
   return this->Target->GetPropertyAsBool(prop);
 }
 
-static void AddInterfaceEntries(
-  cmGeneratorTarget const* thisTarget, std::string const& config,
-  std::string const& prop,
-  std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
+bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
+  std::string const& prop, cmGeneratorExpressionContext* context) const
+{
+  std::string const key = prop + '@' + context->Config;
+  auto i = this->MaybeInterfacePropertyExists.find(key);
+  if (i == this->MaybeInterfacePropertyExists.end()) {
+    // Insert an entry now in case there is a cycle.
+    i = this->MaybeInterfacePropertyExists.emplace(key, false).first;
+    bool& maybeInterfaceProp = i->second;
+
+    // If this target itself has a non-empty property value, we are done.
+    const char* p = this->GetProperty(prop);
+    maybeInterfaceProp = p && *p;
+
+    // Otherwise, recurse to interface dependencies.
+    if (!maybeInterfaceProp) {
+      cmGeneratorTarget const* headTarget =
+        context->HeadTarget ? context->HeadTarget : this;
+      if (cmLinkInterfaceLibraries const* iface =
+            this->GetLinkInterfaceLibraries(context->Config, headTarget,
+                                            true)) {
+        if (iface->HadHeadSensitiveCondition) {
+          // With a different head target we may get to a library with
+          // this interface property.
+          maybeInterfaceProp = true;
+        } else {
+          // The transitive interface libraries do not depend on the
+          // head target, so we can follow them.
+          for (cmLinkItem const& lib : iface->Libraries) {
+            if (lib.Target &&
+                lib.Target->MaybeHaveInterfaceProperty(prop, context)) {
+              maybeInterfaceProp = true;
+              break;
+            }
+          }
+        }
+      }
+    }
+  }
+  return i->second;
+}
+
+std::string cmGeneratorTarget::EvaluateInterfaceProperty(
+  std::string const& prop, cmGeneratorExpressionContext* context,
+  cmGeneratorExpressionDAGChecker* dagCheckerParent) const
+{
+  std::string result;
+
+  // If the property does not appear transitively at all, we are done.
+  if (!this->MaybeHaveInterfaceProperty(prop, context)) {
+    return result;
+  }
+
+  // Evaluate $<TARGET_PROPERTY:this,prop> as if it were compiled.  This is
+  // a subset of TargetPropertyNode::Evaluate without stringify/parse steps
+  // but sufficient for transitive interface properties.
+  cmGeneratorExpressionDAGChecker dagChecker(context->Backtrace, this, prop,
+                                             nullptr, dagCheckerParent);
+  switch (dagChecker.Check()) {
+    case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
+      dagChecker.ReportError(
+        context, "$<TARGET_PROPERTY:" + this->GetName() + "," + prop + ">");
+      return result;
+    case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
+      // No error. We just skip cyclic references.
+      return result;
+    case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
+      // No error. We have already seen this transitive property.
+      return result;
+    case cmGeneratorExpressionDAGChecker::DAG:
+      break;
+  }
+
+  cmGeneratorTarget const* headTarget =
+    context->HeadTarget ? context->HeadTarget : this;
+
+  if (const char* p = this->GetProperty(prop)) {
+    result = cmGeneratorExpressionNode::EvaluateDependentExpression(
+      p, context->LG, context, headTarget, this, &dagChecker);
+  }
+
+  if (cmLinkInterfaceLibraries const* iface =
+        this->GetLinkInterfaceLibraries(context->Config, headTarget, true)) {
+    for (cmLinkItem const& lib : iface->Libraries) {
+      // Broken code can have a target in its own link interface.
+      // Don't follow such link interface entries so as not to create a
+      // self-referencing loop.
+      if (lib.Target && lib.Target != this) {
+        // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in the
+        // above property and hand-evaluate it as if it were compiled.
+        // Create a context as cmCompiledGeneratorExpression::Evaluate does.
+        cmGeneratorExpressionContext libContext(
+          context->LG, context->Config, context->Quiet, headTarget, this,
+          context->EvaluateForBuildsystem, context->Backtrace,
+          context->Language);
+        std::string libResult = cmGeneratorExpression::StripEmptyListElements(
+          lib.Target->EvaluateInterfaceProperty(prop, &libContext,
+                                                &dagChecker));
+        if (!libResult.empty()) {
+          if (result.empty()) {
+            result = std::move(libResult);
+          } else {
+            result.reserve(result.size() + 1 + libResult.size());
+            result += ";";
+            result += libResult;
+          }
+        }
+        context->HadContextSensitiveCondition =
+          context->HadContextSensitiveCondition ||
+          libContext.HadContextSensitiveCondition;
+        context->HadHeadSensitiveCondition =
+          context->HadHeadSensitiveCondition ||
+          libContext.HadHeadSensitiveCondition;
+      }
+    }
+  }
+
+  return result;
+}
+
+namespace {
+void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
+                         std::string const& config, std::string const& prop,
+                         std::string const& lang,
+                         cmGeneratorExpressionDAGChecker* dagChecker,
+                         std::vector<EvaluatedTargetPropertyEntry>& entries)
 {
   if (cmLinkImplementationLibraries const* impl =
-        thisTarget->GetLinkImplementationLibraries(config)) {
+        headTarget->GetLinkImplementationLibraries(config)) {
     for (cmLinkImplItem const& lib : impl->Libraries) {
       if (lib.Target) {
-        std::string uniqueName =
-          thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
-            lib.Target);
-        std::string genex =
-          "$<TARGET_PROPERTY:" + std::move(uniqueName) + "," + prop + ">";
-        cmGeneratorExpression ge(lib.Backtrace);
-        std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
-        cge->SetEvaluateForBuildsystem(true);
-        entries.push_back(new TargetPropertyEntryGenex(std::move(cge), lib));
+        EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
+        // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
+        // caller's property and hand-evaluate it as if it were compiled.
+        // Create a context as cmCompiledGeneratorExpression::Evaluate does.
+        cmGeneratorExpressionContext context(
+          headTarget->GetLocalGenerator(), config, false, headTarget,
+          headTarget, true, lib.Backtrace, lang);
+        cmSystemTools::ExpandListArgument(
+          lib.Target->EvaluateInterfaceProperty(prop, &context, dagChecker),
+          ee.Values);
+        ee.ContextDependent = context.HadContextSensitiveCondition;
+        entries.emplace_back(std::move(ee));
       }
     }
   }
 }
 
-static void AddObjectEntries(
-  cmGeneratorTarget const* thisTarget, std::string const& config,
-  std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries)
+void AddObjectEntries(cmGeneratorTarget const* headTarget,
+                      std::string const& config,
+                      cmGeneratorExpressionDAGChecker* dagChecker,
+                      std::vector<EvaluatedTargetPropertyEntry>& entries)
 {
   if (cmLinkImplementationLibraries const* impl =
-        thisTarget->GetLinkImplementationLibraries(config)) {
+        headTarget->GetLinkImplementationLibraries(config)) {
     for (cmLinkImplItem const& lib : impl->Libraries) {
       if (lib.Target &&
           lib.Target->GetType() == cmStateEnums::OBJECT_LIBRARY) {
         std::string uniqueName =
-          thisTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
+          headTarget->GetGlobalGenerator()->IndexGeneratorTargetUniquely(
             lib.Target);
         std::string genex = "$<TARGET_OBJECTS:" + std::move(uniqueName) + ">";
         cmGeneratorExpression ge(lib.Backtrace);
         std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(genex);
         cge->SetEvaluateForBuildsystem(true);
-        entries.push_back(new TargetPropertyEntryGenex(std::move(cge), lib));
+
+        EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
+        cmSystemTools::ExpandListArgument(
+          cge->Evaluate(headTarget->GetLocalGenerator(), config, false,
+                        headTarget, dagChecker),
+          ee.Values);
+        if (cge->GetHadContextSensitiveCondition()) {
+          ee.ContextDependent = true;
+        }
+        entries.emplace_back(std::move(ee));
       }
     }
   }
 }
 
-static bool processSources(
-  cmGeneratorTarget const* tgt,
-  const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
-  std::vector<BT<std::string>>& srcs,
-  std::unordered_set<std::string>& uniqueSrcs,
-  cmGeneratorExpressionDAGChecker* dagChecker, std::string const& config,
-  bool debugSources)
+bool processSources(cmGeneratorTarget const* tgt,
+                    std::vector<EvaluatedTargetPropertyEntry>& entries,
+                    std::vector<BT<std::string>>& srcs,
+                    std::unordered_set<std::string>& uniqueSrcs,
+                    bool debugSources)
 {
   cmMakefile* mf = tgt->Target->GetMakefile();
 
   bool contextDependent = false;
 
-  for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
-    cmLinkImplItem const& item = entry->LinkImplItem;
-    std::string const& targetName = item.AsStr();
-    std::vector<std::string> entrySources;
-    cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(),
-                                                      config, false, tgt, tgt,
-                                                      dagChecker),
-                                      entrySources);
-
-    if (entry->GetHadContextSensitiveCondition()) {
+  for (EvaluatedTargetPropertyEntry& entry : entries) {
+    if (entry.ContextDependent) {
       contextDependent = true;
     }
 
-    for (std::string& src : entrySources) {
+    cmLinkImplItem const& item = entry.LinkImplItem;
+    std::string const& targetName = item.AsStr();
+
+    for (std::string& src : entry.Values) {
       cmSourceFile* sf = mf->GetOrCreateSource(src);
       std::string e;
       std::string fullPath = sf->GetFullPath(&e);
@@ -1186,9 +1370,9 @@
       src = fullPath;
     }
     std::string usedSources;
-    for (std::string const& src : entrySources) {
+    for (std::string const& src : entry.Values) {
       if (uniqueSrcs.insert(src).second) {
-        srcs.emplace_back(src, entry->GetBacktrace());
+        srcs.emplace_back(src, entry.Backtrace);
         if (debugSources) {
           usedSources += " * " + src + "\n";
         }
@@ -1199,11 +1383,12 @@
         MessageType::LOG,
         std::string("Used sources for target ") + tgt->GetName() + ":\n" +
           usedSources,
-        entry->GetBacktrace());
+        entry.Backtrace);
     }
   }
   return contextDependent;
 }
+}
 
 std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
   std::string const& config) const
@@ -1251,28 +1436,28 @@
   cmGeneratorExpressionDAGChecker dagChecker(this, "SOURCES", nullptr,
                                              nullptr);
 
+  std::vector<EvaluatedTargetPropertyEntry> entries =
+    EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker,
+                                  this->SourceEntries);
+
   std::unordered_set<std::string> uniqueSrcs;
   bool contextDependentDirectSources =
-    processSources(this, this->SourceEntries, files, uniqueSrcs, &dagChecker,
-                   config, debugSources);
+    processSources(this, entries, files, uniqueSrcs, debugSources);
 
   // Collect INTERFACE_SOURCES of all direct link-dependencies.
-  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
-    linkInterfaceSourcesEntries;
-  AddInterfaceEntries(this, config, "INTERFACE_SOURCES",
-                      linkInterfaceSourcesEntries);
+  std::vector<EvaluatedTargetPropertyEntry> linkInterfaceSourcesEntries;
+  AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(),
+                      &dagChecker, linkInterfaceSourcesEntries);
   std::vector<std::string>::size_type numFilesBefore = files.size();
-  bool contextDependentInterfaceSources =
-    processSources(this, linkInterfaceSourcesEntries, files, uniqueSrcs,
-                   &dagChecker, config, debugSources);
+  bool contextDependentInterfaceSources = processSources(
+    this, linkInterfaceSourcesEntries, files, uniqueSrcs, debugSources);
 
   // Collect TARGET_OBJECTS of direct object link-dependencies.
-  std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkObjectsEntries;
-  AddObjectEntries(this, config, linkObjectsEntries);
+  std::vector<EvaluatedTargetPropertyEntry> linkObjectsEntries;
+  AddObjectEntries(this, config, &dagChecker, linkObjectsEntries);
   std::vector<std::string>::size_type numFilesBefore2 = files.size();
   bool contextDependentObjects =
-    processSources(this, linkObjectsEntries, files, uniqueSrcs, &dagChecker,
-                   config, debugSources);
+    processSources(this, linkObjectsEntries, files, uniqueSrcs, debugSources);
 
   if (!contextDependentDirectSources &&
       !(contextDependentInterfaceSources && numFilesBefore < files.size()) &&
@@ -1280,8 +1465,6 @@
     this->LinkImplementationLanguageIsContextDependent = false;
   }
 
-  cmDeleteAll(linkInterfaceSourcesEntries);
-  cmDeleteAll(linkObjectsEntries);
   return files;
 }
 
@@ -1858,16 +2041,17 @@
   return this->GetLibraryNames(config).SharedObject;
 }
 
-static bool shouldAddFullLevel(cmGeneratorTarget::BundleDirectoryLevel level)
+namespace {
+bool shouldAddFullLevel(cmGeneratorTarget::BundleDirectoryLevel level)
 {
   return level == cmGeneratorTarget::FullLevel;
 }
 
-static bool shouldAddContentLevel(
-  cmGeneratorTarget::BundleDirectoryLevel level)
+bool shouldAddContentLevel(cmGeneratorTarget::BundleDirectoryLevel level)
 {
   return level == cmGeneratorTarget::ContentLevel || shouldAddFullLevel(level);
 }
+}
 
 std::string cmGeneratorTarget::GetAppBundleDirectory(
   const std::string& config, BundleDirectoryLevel level) const
@@ -2357,7 +2541,7 @@
 
 bool cmGeneratorTarget::IsDLLPlatform() const
 {
-  return this->DLLPlatform;
+  return this->Target->IsDLLPlatform();
 }
 
 void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result,
@@ -2757,33 +2941,35 @@
     case cmStateEnums::MODULE_LIBRARY:
       return "CMAKE_" + lang + "_CREATE_SHARED_MODULE";
     case cmStateEnums::EXECUTABLE:
+      if (this->IsExecutableWithExports()) {
+        std::string linkExeWithExports =
+          "CMAKE_" + lang + "_LINK_EXECUTABLE_WITH_EXPORTS";
+        if (this->Makefile->IsDefinitionSet(linkExeWithExports)) {
+          return linkExeWithExports;
+        }
+      }
       return "CMAKE_" + lang + "_LINK_EXECUTABLE";
     default:
       break;
   }
   return "";
 }
-static void processIncludeDirectories(
+
+namespace {
+void processIncludeDirectories(
   cmGeneratorTarget const* tgt,
-  const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
+  std::vector<EvaluatedTargetPropertyEntry>& entries,
   std::vector<BT<std::string>>& includes,
-  std::unordered_set<std::string>& uniqueIncludes,
-  cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
-  bool debugIncludes, const std::string& language)
+  std::unordered_set<std::string>& uniqueIncludes, bool debugIncludes)
 {
-  for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
-    cmLinkImplItem const& item = entry->LinkImplItem;
+  for (EvaluatedTargetPropertyEntry& entry : entries) {
+    cmLinkImplItem const& item = entry.LinkImplItem;
     std::string const& targetName = item.AsStr();
     bool const fromImported = item.Target && item.Target->IsImported();
     bool const checkCMP0027 = item.FromGenex;
-    std::vector<std::string> entryIncludes;
-    cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(),
-                                                      config, false, tgt,
-                                                      dagChecker, language),
-                                      entryIncludes);
 
     std::string usedIncludes;
-    for (std::string& entryInclude : entryIncludes) {
+    for (std::string& entryInclude : entry.Values) {
       if (fromImported && !cmSystemTools::FileExists(entryInclude)) {
         std::ostringstream e;
         MessageType messageType = MessageType::FATAL_ERROR;
@@ -2855,12 +3041,11 @@
       if (!cmSystemTools::IsOff(entryInclude)) {
         cmSystemTools::ConvertToUnixSlashes(entryInclude);
       }
-      std::string inc = entryInclude;
 
-      if (uniqueIncludes.insert(inc).second) {
-        includes.emplace_back(inc, entry->GetBacktrace());
+      if (uniqueIncludes.insert(entryInclude).second) {
+        includes.emplace_back(entryInclude, entry.Backtrace);
         if (debugIncludes) {
-          usedIncludes += " * " + inc + "\n";
+          usedIncludes += " * " + entryInclude + "\n";
         }
       }
     }
@@ -2869,10 +3054,11 @@
         MessageType::LOG,
         std::string("Used includes for target ") + tgt->GetName() + ":\n" +
           usedIncludes,
-        entry->GetBacktrace());
+        entry.Backtrace);
     }
   }
 }
+}
 
 std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
   const std::string& config, const std::string& lang) const
@@ -2898,14 +3084,12 @@
     this->DebugIncludesDone = true;
   }
 
-  processIncludeDirectories(this, this->IncludeDirectoriesEntries, includes,
-                            uniqueIncludes, &dagChecker, config, debugIncludes,
-                            lang);
+  std::vector<EvaluatedTargetPropertyEntry> entries =
+    EvaluateTargetPropertyEntries(this, config, lang, &dagChecker,
+                                  this->IncludeDirectoriesEntries);
 
-  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
-    linkInterfaceIncludeDirectoriesEntries;
-  AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES",
-                      linkInterfaceIncludeDirectoriesEntries);
+  AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
+                      &dagChecker, entries);
 
   if (this->Makefile->IsOn("APPLE")) {
     cmLinkImplementationLibraries const* impl =
@@ -2921,16 +3105,14 @@
 
       libDir = frameworkCheck.match(1);
 
-      linkInterfaceIncludeDirectoriesEntries.push_back(
-        CreateTargetPropertyEntry(libDir));
+      EvaluatedTargetPropertyEntry ee(lib, cmListFileBacktrace());
+      ee.Values.emplace_back(std::move(libDir));
+      entries.emplace_back(std::move(ee));
     }
   }
 
-  processIncludeDirectories(this, linkInterfaceIncludeDirectoriesEntries,
-                            includes, uniqueIncludes, &dagChecker, config,
-                            debugIncludes, lang);
-
-  cmDeleteAll(linkInterfaceIncludeDirectoriesEntries);
+  processIncludeDirectories(this, entries, includes, uniqueIncludes,
+                            debugIncludes);
 
   return includes;
 }
@@ -2941,33 +3123,26 @@
   Shell
 };
 
-static void processOptionsInternal(
-  cmGeneratorTarget const* tgt,
-  const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
-  std::vector<BT<std::string>>& options,
-  std::unordered_set<std::string>& uniqueOptions,
-  cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
-  bool debugOptions, const char* logName, std::string const& language,
-  OptionsParse parse)
+namespace {
+void processOptions(cmGeneratorTarget const* tgt,
+                    std::vector<EvaluatedTargetPropertyEntry> const& entries,
+                    std::vector<BT<std::string>>& options,
+                    std::unordered_set<std::string>& uniqueOptions,
+                    bool debugOptions, const char* logName, OptionsParse parse)
 {
-  for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
-    std::vector<std::string> entryOptions;
-    cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(),
-                                                      config, false, tgt,
-                                                      dagChecker, language),
-                                      entryOptions);
+  for (EvaluatedTargetPropertyEntry const& entry : entries) {
     std::string usedOptions;
-    for (std::string const& opt : entryOptions) {
+    for (std::string const& opt : entry.Values) {
       if (uniqueOptions.insert(opt).second) {
         if (parse == OptionsParse::Shell &&
             cmHasLiteralPrefix(opt, "SHELL:")) {
           std::vector<std::string> tmp;
           cmSystemTools::ParseUnixCommandLine(opt.c_str() + 6, tmp);
           for (std::string& o : tmp) {
-            options.emplace_back(std::move(o), entry->GetBacktrace());
+            options.emplace_back(std::move(o), entry.Backtrace);
           }
         } else {
-          options.emplace_back(opt, entry->GetBacktrace());
+          options.emplace_back(opt, entry.Backtrace);
         }
         if (debugOptions) {
           usedOptions += " * " + opt + "\n";
@@ -2979,22 +3154,10 @@
         MessageType::LOG,
         std::string("Used ") + logName + std::string(" for target ") +
           tgt->GetName() + ":\n" + usedOptions,
-        entry->GetBacktrace());
+        entry.Backtrace);
     }
   }
 }
-
-static void processCompileOptions(
-  cmGeneratorTarget const* tgt,
-  const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
-  std::vector<BT<std::string>>& options,
-  std::unordered_set<std::string>& uniqueOptions,
-  cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
-  bool debugOptions, std::string const& language)
-{
-  processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
-                         config, debugOptions, "compile options", language,
-                         OptionsParse::Shell);
 }
 
 void cmGeneratorTarget::GetCompileOptions(std::vector<std::string>& result,
@@ -3032,37 +3195,19 @@
     this->DebugCompileOptionsDone = true;
   }
 
-  processCompileOptions(this, this->CompileOptionsEntries, result,
-                        uniqueOptions, &dagChecker, config, debugOptions,
-                        language);
+  std::vector<EvaluatedTargetPropertyEntry> entries =
+    EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+                                  this->CompileOptionsEntries);
 
-  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
-    linkInterfaceCompileOptionsEntries;
+  AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS", language,
+                      &dagChecker, entries);
 
-  AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS",
-                      linkInterfaceCompileOptionsEntries);
+  processOptions(this, entries, result, uniqueOptions, debugOptions,
+                 "compile options", OptionsParse::Shell);
 
-  processCompileOptions(this, linkInterfaceCompileOptionsEntries, result,
-                        uniqueOptions, &dagChecker, config, debugOptions,
-                        language);
-
-  cmDeleteAll(linkInterfaceCompileOptionsEntries);
   return result;
 }
 
-static void processCompileFeatures(
-  cmGeneratorTarget const* tgt,
-  const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
-  std::vector<BT<std::string>>& options,
-  std::unordered_set<std::string>& uniqueOptions,
-  cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
-  bool debugOptions)
-{
-  processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
-                         config, debugOptions, "compile features",
-                         std::string(), OptionsParse::None);
-}
-
 void cmGeneratorTarget::GetCompileFeatures(std::vector<std::string>& result,
                                            const std::string& config) const
 {
@@ -3097,34 +3242,19 @@
     this->DebugCompileFeaturesDone = true;
   }
 
-  processCompileFeatures(this, this->CompileFeaturesEntries, result,
-                         uniqueFeatures, &dagChecker, config, debugFeatures);
+  std::vector<EvaluatedTargetPropertyEntry> entries =
+    EvaluateTargetPropertyEntries(this, config, std::string(), &dagChecker,
+                                  this->CompileFeaturesEntries);
 
-  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
-    linkInterfaceCompileFeaturesEntries;
   AddInterfaceEntries(this, config, "INTERFACE_COMPILE_FEATURES",
-                      linkInterfaceCompileFeaturesEntries);
+                      std::string(), &dagChecker, entries);
 
-  processCompileFeatures(this, linkInterfaceCompileFeaturesEntries, result,
-                         uniqueFeatures, &dagChecker, config, debugFeatures);
+  processOptions(this, entries, result, uniqueFeatures, debugFeatures,
+                 "compile features", OptionsParse::None);
 
-  cmDeleteAll(linkInterfaceCompileFeaturesEntries);
   return result;
 }
 
-static void processCompileDefinitions(
-  cmGeneratorTarget const* tgt,
-  const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
-  std::vector<BT<std::string>>& options,
-  std::unordered_set<std::string>& uniqueOptions,
-  cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
-  bool debugOptions, std::string const& language)
-{
-  processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
-                         config, debugOptions, "compile definitions", language,
-                         OptionsParse::None);
-}
-
 void cmGeneratorTarget::GetCompileDefinitions(
   std::vector<std::string>& result, const std::string& config,
   const std::string& language) const
@@ -3161,14 +3291,13 @@
     this->DebugCompileDefinitionsDone = true;
   }
 
-  processCompileDefinitions(this, this->CompileDefinitionsEntries, list,
-                            uniqueOptions, &dagChecker, config, debugDefines,
-                            language);
+  std::vector<EvaluatedTargetPropertyEntry> entries =
+    EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+                                  this->CompileDefinitionsEntries);
 
-  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
-    linkInterfaceCompileDefinitionsEntries;
-  AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS",
-                      linkInterfaceCompileDefinitionsEntries);
+  AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS", language,
+                      &dagChecker, entries);
+
   if (!config.empty()) {
     std::string configPropName =
       "COMPILE_DEFINITIONS_" + cmSystemTools::UpperCase(config);
@@ -3183,8 +3312,10 @@
           CM_FALLTHROUGH;
         }
         case cmPolicies::OLD: {
-          linkInterfaceCompileDefinitionsEntries.push_back(
+          std::unique_ptr<TargetPropertyEntry> entry(
             CreateTargetPropertyEntry(configProp));
+          entries.emplace_back(EvaluateTargetPropertyEntry(
+            this, config, language, &dagChecker, entry.get()));
         } break;
         case cmPolicies::NEW:
         case cmPolicies::REQUIRED_ALWAYS:
@@ -3194,29 +3325,12 @@
     }
   }
 
-  processCompileDefinitions(this, linkInterfaceCompileDefinitionsEntries, list,
-                            uniqueOptions, &dagChecker, config, debugDefines,
-                            language);
+  processOptions(this, entries, list, uniqueOptions, debugDefines,
+                 "compile definitions", OptionsParse::None);
 
-  cmDeleteAll(linkInterfaceCompileDefinitionsEntries);
   return list;
 }
 
-namespace {
-void processLinkOptions(
-  cmGeneratorTarget const* tgt,
-  const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
-  std::vector<BT<std::string>>& options,
-  std::unordered_set<std::string>& uniqueOptions,
-  cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
-  bool debugOptions, std::string const& language)
-{
-  processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
-                         config, debugOptions, "link options", language,
-                         OptionsParse::Shell);
-}
-}
-
 void cmGeneratorTarget::GetLinkOptions(std::vector<std::string>& result,
                                        const std::string& config,
                                        const std::string& language) const
@@ -3252,20 +3366,15 @@
     this->DebugLinkOptionsDone = true;
   }
 
-  processLinkOptions(this, this->LinkOptionsEntries, result, uniqueOptions,
-                     &dagChecker, config, debugOptions, language);
+  std::vector<EvaluatedTargetPropertyEntry> entries =
+    EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+                                  this->LinkOptionsEntries);
 
-  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
-    linkInterfaceLinkOptionsEntries;
+  AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", language,
+                      &dagChecker, entries);
 
-  AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS",
-                      linkInterfaceLinkOptionsEntries);
-
-  processLinkOptions(this, linkInterfaceLinkOptionsEntries, result,
-                     uniqueOptions, &dagChecker, config, debugOptions,
-                     language);
-
-  cmDeleteAll(linkInterfaceLinkOptionsEntries);
+  processOptions(this, entries, result, uniqueOptions, debugOptions,
+                 "link options", OptionsParse::Shell);
 
   // Last step: replace "LINKER:" prefixed elements by
   // actual linker wrapper
@@ -3371,21 +3480,6 @@
   return result;
 }
 
-namespace {
-void processStaticLibraryLinkOptions(
-  cmGeneratorTarget const* tgt,
-  const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
-  std::vector<BT<std::string>>& options,
-  std::unordered_set<std::string>& uniqueOptions,
-  cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
-  std::string const& language)
-{
-  processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
-                         config, false, "static library link options",
-                         language, OptionsParse::Shell);
-}
-}
-
 void cmGeneratorTarget::GetStaticLibraryLinkOptions(
   std::vector<std::string>& result, const std::string& config,
   const std::string& language) const
@@ -3402,47 +3496,41 @@
   std::string const& config, std::string const& language) const
 {
   std::vector<BT<std::string>> result;
-  std::vector<cmGeneratorTarget::TargetPropertyEntry*> entries;
   std::unordered_set<std::string> uniqueOptions;
 
   cmGeneratorExpressionDAGChecker dagChecker(this, "STATIC_LIBRARY_OPTIONS",
                                              nullptr, nullptr);
 
+  std::vector<EvaluatedTargetPropertyEntry> entries;
   if (const char* linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
     std::vector<std::string> options;
     cmSystemTools::ExpandListArgument(linkOptions, options);
     for (const auto& option : options) {
-      entries.push_back(CreateTargetPropertyEntry(option));
+      std::unique_ptr<TargetPropertyEntry> entry(
+        CreateTargetPropertyEntry(option));
+      entries.emplace_back(EvaluateTargetPropertyEntry(
+        this, config, language, &dagChecker, entry.get()));
     }
   }
-  processStaticLibraryLinkOptions(this, entries, result, uniqueOptions,
-                                  &dagChecker, config, language);
+  processOptions(this, entries, result, uniqueOptions, false,
+                 "static library link options", OptionsParse::Shell);
 
-  cmDeleteAll(entries);
   return result;
 }
 
 namespace {
-void processLinkDirectories(
-  cmGeneratorTarget const* tgt,
-  const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
-  std::vector<BT<std::string>>& directories,
-  std::unordered_set<std::string>& uniqueDirectories,
-  cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
-  bool debugDirectories, std::string const& language)
+void processLinkDirectories(cmGeneratorTarget const* tgt,
+                            std::vector<EvaluatedTargetPropertyEntry>& entries,
+                            std::vector<BT<std::string>>& directories,
+                            std::unordered_set<std::string>& uniqueDirectories,
+                            bool debugDirectories)
 {
-  for (cmGeneratorTarget::TargetPropertyEntry* entry : entries) {
-    cmLinkImplItem const& item = entry->LinkImplItem;
+  for (EvaluatedTargetPropertyEntry& entry : entries) {
+    cmLinkImplItem const& item = entry.LinkImplItem;
     std::string const& targetName = item.AsStr();
 
-    std::vector<std::string> entryDirectories;
-    cmSystemTools::ExpandListArgument(entry->Evaluate(tgt->GetLocalGenerator(),
-                                                      config, false, tgt,
-                                                      dagChecker, language),
-                                      entryDirectories);
-
     std::string usedDirectories;
-    for (std::string& entryDirectory : entryDirectories) {
+    for (std::string& entryDirectory : entry.Values) {
       if (!cmSystemTools::FileIsFullPath(entryDirectory)) {
         std::ostringstream e;
         bool noMessage = false;
@@ -3495,7 +3583,7 @@
         MessageType::LOG,
         std::string("Used link directories for target ") + tgt->GetName() +
           ":\n" + usedDirectories,
-        entry->GetBacktrace());
+        entry.Backtrace);
     }
   }
 }
@@ -3537,39 +3625,19 @@
     this->DebugLinkDirectoriesDone = true;
   }
 
-  processLinkDirectories(this, this->LinkDirectoriesEntries, result,
-                         uniqueDirectories, &dagChecker, config,
-                         debugDirectories, language);
+  std::vector<EvaluatedTargetPropertyEntry> entries =
+    EvaluateTargetPropertyEntries(this, config, language, &dagChecker,
+                                  this->LinkDirectoriesEntries);
 
-  std::vector<cmGeneratorTarget::TargetPropertyEntry*>
-    linkInterfaceLinkDirectoriesEntries;
+  AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", language,
+                      &dagChecker, entries);
 
-  AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES",
-                      linkInterfaceLinkDirectoriesEntries);
+  processLinkDirectories(this, entries, result, uniqueDirectories,
+                         debugDirectories);
 
-  processLinkDirectories(this, linkInterfaceLinkDirectoriesEntries, result,
-                         uniqueDirectories, &dagChecker, config,
-                         debugDirectories, language);
-
-  cmDeleteAll(linkInterfaceLinkDirectoriesEntries);
   return result;
 }
 
-namespace {
-void processLinkDepends(
-  cmGeneratorTarget const* tgt,
-  const std::vector<cmGeneratorTarget::TargetPropertyEntry*>& entries,
-  std::vector<BT<std::string>>& options,
-  std::unordered_set<std::string>& uniqueOptions,
-  cmGeneratorExpressionDAGChecker* dagChecker, const std::string& config,
-  std::string const& language)
-{
-  processOptionsInternal(tgt, entries, options, uniqueOptions, dagChecker,
-                         config, false, "link depends", language,
-                         OptionsParse::None);
-}
-}
-
 void cmGeneratorTarget::GetLinkDepends(std::vector<std::string>& result,
                                        const std::string& config,
                                        const std::string& language) const
@@ -3585,24 +3653,27 @@
   std::string const& config, std::string const& language) const
 {
   std::vector<BT<std::string>> result;
-  std::vector<cmGeneratorTarget::TargetPropertyEntry*> linkDependsEntries;
   std::unordered_set<std::string> uniqueOptions;
   cmGeneratorExpressionDAGChecker dagChecker(this, "LINK_DEPENDS", nullptr,
                                              nullptr);
 
+  std::vector<EvaluatedTargetPropertyEntry> entries;
   if (const char* linkDepends = this->GetProperty("LINK_DEPENDS")) {
     std::vector<std::string> depends;
     cmSystemTools::ExpandListArgument(linkDepends, depends);
     for (const auto& depend : depends) {
-      linkDependsEntries.push_back(CreateTargetPropertyEntry(depend));
+      std::unique_ptr<TargetPropertyEntry> entry(
+        CreateTargetPropertyEntry(depend));
+      entries.emplace_back(EvaluateTargetPropertyEntry(
+        this, config, language, &dagChecker, entry.get()));
     }
   }
-  AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS",
-                      linkDependsEntries);
-  processLinkDepends(this, linkDependsEntries, result, uniqueOptions,
-                     &dagChecker, config, language);
+  AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", language,
+                      &dagChecker, entries);
 
-  cmDeleteAll(linkDependsEntries);
+  processOptions(this, entries, result, uniqueOptions, false, "link depends",
+                 OptionsParse::None);
+
   return result;
 }
 
@@ -3924,8 +3995,7 @@
 
   // Return an empty name for the import library if this platform
   // does not support import libraries.
-  if (isImportedLibraryArtifact &&
-      !this->Makefile->GetDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX")) {
+  if (isImportedLibraryArtifact && !this->NeedImportLibraryName(config)) {
     outPrefix.clear();
     outBase.clear();
     outSuffix.clear();
@@ -3934,8 +4004,8 @@
 
   // retrieve prefix and suffix
   std::string ll = this->GetLinkerLanguage(config);
-  const char* targetPrefix = this->GetFilePrefixInternal(artifact, ll);
-  const char* targetSuffix = this->GetFileSuffixInternal(artifact, ll);
+  const char* targetPrefix = this->GetFilePrefixInternal(config, artifact, ll);
+  const char* targetSuffix = this->GetFileSuffixInternal(config, artifact, ll);
 
   // The implib option is only allowed for shared libraries, module
   // libraries, and executables.
@@ -4343,8 +4413,9 @@
   }
 }
 
-static std::string intersect(const std::set<std::string>& s1,
-                             const std::set<std::string>& s2)
+namespace {
+std::string intersect(const std::set<std::string>& s1,
+                      const std::set<std::string>& s2)
 {
   std::set<std::string> intersect;
   std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(),
@@ -4355,9 +4426,9 @@
   return "";
 }
 
-static std::string intersect(const std::set<std::string>& s1,
-                             const std::set<std::string>& s2,
-                             const std::set<std::string>& s3)
+std::string intersect(const std::set<std::string>& s1,
+                      const std::set<std::string>& s2,
+                      const std::set<std::string>& s3)
 {
   std::string result;
   result = intersect(s1, s2);
@@ -4371,10 +4442,10 @@
   return intersect(s2, s3);
 }
 
-static std::string intersect(const std::set<std::string>& s1,
-                             const std::set<std::string>& s2,
-                             const std::set<std::string>& s3,
-                             const std::set<std::string>& s4)
+std::string intersect(const std::set<std::string>& s1,
+                      const std::set<std::string>& s2,
+                      const std::set<std::string>& s3,
+                      const std::set<std::string>& s4)
 {
   std::string result;
   result = intersect(s1, s2);
@@ -4391,6 +4462,7 @@
   }
   return intersect(s2, s3, s4);
 }
+}
 
 void cmGeneratorTarget::CheckPropertyCompatibility(
   cmComputeLinkInformation* info, const std::string& config) const
@@ -6360,7 +6432,18 @@
            this->IsExecutableWithExports()) &&
           // Assemblies which have only managed code do not have
           // import libraries.
-          this->GetManagedType(config) != ManagedType::Managed);
+          this->GetManagedType(config) != ManagedType::Managed) ||
+    (this->Target->IsAIX() && this->IsExecutableWithExports());
+}
+
+bool cmGeneratorTarget::NeedImportLibraryName(std::string const& config) const
+{
+  return this->HasImportLibrary(config) ||
+    // On DLL platforms we always generate the import library name
+    // just in case the sources have export markup.
+    (this->IsDLLPlatform() &&
+     (this->GetType() == cmStateEnums::EXECUTABLE ||
+      this->GetType() == cmStateEnums::MODULE_LIBRARY));
 }
 
 std::string cmGeneratorTarget::GetSupportDirectory() const
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 627a055..3874738 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -14,6 +14,7 @@
 #include <set>
 #include <stddef.h>
 #include <string>
+#include <unordered_map>
 #include <utility>
 #include <vector>
 
@@ -25,6 +26,9 @@
 class cmSourceFile;
 class cmTarget;
 
+struct cmGeneratorExpressionContext;
+struct cmGeneratorExpressionDAGChecker;
+
 class cmGeneratorTarget
 {
 public:
@@ -674,6 +678,10 @@
 
   class TargetPropertyEntry;
 
+  std::string EvaluateInterfaceProperty(
+    std::string const& prop, cmGeneratorExpressionContext* context,
+    cmGeneratorExpressionDAGChecker* dagCheckerParent) const;
+
   bool HaveInstallTreeRPATH(const std::string& config) const;
 
   bool GetBuildRPATH(const std::string& config, std::string& rpath) const;
@@ -743,9 +751,13 @@
 
   mutable std::map<std::string, bool> DebugCompatiblePropertiesDone;
 
-  const char* GetFilePrefixInternal(cmStateEnums::ArtifactType artifact,
+  bool NeedImportLibraryName(std::string const& config) const;
+
+  const char* GetFilePrefixInternal(std::string const& config,
+                                    cmStateEnums::ArtifactType artifact,
                                     const std::string& language = "") const;
-  const char* GetFileSuffixInternal(cmStateEnums::ArtifactType artifact,
+  const char* GetFileSuffixInternal(std::string const& config,
+                                    cmStateEnums::ArtifactType artifact,
                                     const std::string& language = "") const;
 
   std::string GetFullNameInternal(const std::string& config,
@@ -845,6 +857,10 @@
   mutable std::vector<AllConfigSource> AllConfigSources;
   void ComputeAllConfigSources() const;
 
+  mutable std::unordered_map<std::string, bool> MaybeInterfacePropertyExists;
+  bool MaybeHaveInterfaceProperty(std::string const& prop,
+                                  cmGeneratorExpressionContext* context) const;
+
   std::vector<TargetPropertyEntry*> IncludeDirectoriesEntries;
   std::vector<TargetPropertyEntry*> CompileOptionsEntries;
   std::vector<TargetPropertyEntry*> CompileFeaturesEntries;
@@ -909,7 +925,6 @@
   mutable bool DebugSourcesDone;
   mutable bool LinkImplementationLanguageIsContextDependent;
   mutable bool UtilityItemsDone;
-  bool DLLPlatform;
 
   bool ComputePDBOutputDir(const std::string& kind, const std::string& config,
                            std::string& out) const;
diff --git a/Source/cmGetCMakePropertyCommand.cxx b/Source/cmGetCMakePropertyCommand.cxx
index fc82fee..8538944 100644
--- a/Source/cmGetCMakePropertyCommand.cxx
+++ b/Source/cmGetCMakePropertyCommand.cxx
@@ -46,7 +46,7 @@
     }
   }
 
-  this->Makefile->AddDefinition(variable, output.c_str());
+  this->Makefile->AddDefinition(variable, output);
 
   return true;
 }
diff --git a/Source/cmGetCMakePropertyCommand.h b/Source/cmGetCMakePropertyCommand.h
index 1f29c78..7790a6b 100644
--- a/Source/cmGetCMakePropertyCommand.h
+++ b/Source/cmGetCMakePropertyCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,7 +17,10 @@
 class cmGetCMakePropertyCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmGetCMakePropertyCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmGetCMakePropertyCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmGetDirectoryPropertyCommand.cxx b/Source/cmGetDirectoryPropertyCommand.cxx
index a92eb71..98ccb0a 100644
--- a/Source/cmGetDirectoryPropertyCommand.cxx
+++ b/Source/cmGetDirectoryPropertyCommand.cxx
@@ -66,7 +66,7 @@
       return false;
     }
     std::string const& output = dir->GetSafeDefinition(*i);
-    this->Makefile->AddDefinition(variable, output.c_str());
+    this->Makefile->AddDefinition(variable, output);
     return true;
   }
 
@@ -97,9 +97,5 @@
 void cmGetDirectoryPropertyCommand::StoreResult(std::string const& variable,
                                                 const char* prop)
 {
-  if (prop) {
-    this->Makefile->AddDefinition(variable, prop);
-    return;
-  }
-  this->Makefile->AddDefinition(variable, "");
+  this->Makefile->AddDefinition(variable, prop ? prop : "");
 }
diff --git a/Source/cmGetDirectoryPropertyCommand.h b/Source/cmGetDirectoryPropertyCommand.h
index 02ea056..63a198a 100644
--- a/Source/cmGetDirectoryPropertyCommand.h
+++ b/Source/cmGetDirectoryPropertyCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,7 +17,10 @@
 class cmGetDirectoryPropertyCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmGetDirectoryPropertyCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmGetDirectoryPropertyCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmGetFilenameComponentCommand.cxx b/Source/cmGetFilenameComponentCommand.cxx
index 163b4c8..fc82535 100644
--- a/Source/cmGetFilenameComponentCommand.cxx
+++ b/Source/cmGetFilenameComponentCommand.cxx
@@ -128,9 +128,9 @@
       args[2] == "PATH" ? cmStateEnums::FILEPATH : cmStateEnums::STRING);
   } else {
     if (!programArgs.empty() && !storeArgs.empty()) {
-      this->Makefile->AddDefinition(storeArgs, programArgs.c_str());
+      this->Makefile->AddDefinition(storeArgs, programArgs);
     }
-    this->Makefile->AddDefinition(args.front(), result.c_str());
+    this->Makefile->AddDefinition(args.front(), result);
   }
 
   return true;
diff --git a/Source/cmGetFilenameComponentCommand.h b/Source/cmGetFilenameComponentCommand.h
index 8c26655..1780b96 100644
--- a/Source/cmGetFilenameComponentCommand.h
+++ b/Source/cmGetFilenameComponentCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmGetFilenameComponentCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmGetFilenameComponentCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmGetPropertyCommand.cxx b/Source/cmGetPropertyCommand.cxx
index 039f439..de462ed 100644
--- a/Source/cmGetPropertyCommand.cxx
+++ b/Source/cmGetPropertyCommand.cxx
@@ -121,7 +121,7 @@
     } else {
       output = "NOTFOUND";
     }
-    this->Makefile->AddDefinition(this->Variable, output.c_str());
+    this->Makefile->AddDefinition(this->Variable, output);
   } else if (this->InfoType == OutFullDoc) {
     // Lookup full documentation.
     std::string output;
@@ -132,7 +132,7 @@
     } else {
       output = "NOTFOUND";
     }
-    this->Makefile->AddDefinition(this->Variable, output.c_str());
+    this->Makefile->AddDefinition(this->Variable, output);
   } else if (this->InfoType == OutDefined) {
     // Lookup if the property is defined
     if (this->Makefile->GetState()->GetPropertyDefinition(this->PropertyName,
diff --git a/Source/cmGetPropertyCommand.h b/Source/cmGetPropertyCommand.h
index c3f653e..50e4014 100644
--- a/Source/cmGetPropertyCommand.h
+++ b/Source/cmGetPropertyCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -17,7 +19,10 @@
 public:
   cmGetPropertyCommand();
 
-  cmCommand* Clone() override { return new cmGetPropertyCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmGetPropertyCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmGetSourceFilePropertyCommand.cxx b/Source/cmGetSourceFilePropertyCommand.cxx
index 75879a5..a16076d 100644
--- a/Source/cmGetSourceFilePropertyCommand.cxx
+++ b/Source/cmGetSourceFilePropertyCommand.cxx
@@ -25,7 +25,7 @@
   }
   if (sf) {
     if (args[2] == "LANGUAGE") {
-      this->Makefile->AddDefinition(var, sf->GetLanguage().c_str());
+      this->Makefile->AddDefinition(var, sf->GetLanguage());
       return true;
     }
     const char* prop = nullptr;
diff --git a/Source/cmGetSourceFilePropertyCommand.h b/Source/cmGetSourceFilePropertyCommand.h
index 43bc330..387a7f4 100644
--- a/Source/cmGetSourceFilePropertyCommand.h
+++ b/Source/cmGetSourceFilePropertyCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,7 +17,10 @@
 class cmGetSourceFilePropertyCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmGetSourceFilePropertyCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmGetSourceFilePropertyCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmGetTargetPropertyCommand.cxx b/Source/cmGetTargetPropertyCommand.cxx
index fc0e9c6..07aaf02 100644
--- a/Source/cmGetTargetPropertyCommand.cxx
+++ b/Source/cmGetTargetPropertyCommand.cxx
@@ -75,9 +75,9 @@
     }
   }
   if (prop_exists) {
-    this->Makefile->AddDefinition(var, prop.c_str());
+    this->Makefile->AddDefinition(var, prop);
     return true;
   }
-  this->Makefile->AddDefinition(var, (var + "-NOTFOUND").c_str());
+  this->Makefile->AddDefinition(var, var + "-NOTFOUND");
   return true;
 }
diff --git a/Source/cmGetTargetPropertyCommand.h b/Source/cmGetTargetPropertyCommand.h
index 63ee5fd..1a53195 100644
--- a/Source/cmGetTargetPropertyCommand.h
+++ b/Source/cmGetTargetPropertyCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,7 +17,10 @@
 class cmGetTargetPropertyCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmGetTargetPropertyCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmGetTargetPropertyCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmGetTestPropertyCommand.h b/Source/cmGetTestPropertyCommand.h
index 4a74f59..a53a7f7 100644
--- a/Source/cmGetTestPropertyCommand.h
+++ b/Source/cmGetTestPropertyCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,7 +17,10 @@
 class cmGetTestPropertyCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmGetTestPropertyCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmGetTestPropertyCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index ec4107b..7b8ffc5 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -511,7 +511,7 @@
 
   bool fatalError = false;
 
-  mf->AddDefinition("RUN_CONFIGURE", true);
+  mf->AddDefinitionBool("RUN_CONFIGURE", true);
   std::string rootBin = this->CMakeInstance->GetHomeOutputDirectory();
   rootBin += "/CMakeFiles";
 
@@ -525,7 +525,7 @@
   rootBin += cmVersion::GetCMakeVersion();
 
   // set the dir for parent files so they can be used by modules
-  mf->AddDefinition("CMAKE_PLATFORM_INFO_DIR", rootBin.c_str());
+  mf->AddDefinition("CMAKE_PLATFORM_INFO_DIR", rootBin);
 
   if (!this->CMakeInstance->GetIsInTryCompile()) {
     // Keep a mark in the cache to indicate that we've initialized the
@@ -585,8 +585,7 @@
     windowsVersionString << osviex.dwMajorVersion << "."
                          << osviex.dwMinorVersion << "."
                          << osviex.dwBuildNumber;
-    mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
-                      windowsVersionString.str().c_str());
+    mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", windowsVersionString.str());
 #endif
     // Read the DetermineSystem file
     std::string systemFile = mf->GetModulesFile("CMakeDetermineSystem.cmake");
diff --git a/Source/cmGlobalGhsMultiGenerator.cxx b/Source/cmGlobalGhsMultiGenerator.cxx
index b69dea0..7cfbea6 100644
--- a/Source/cmGlobalGhsMultiGenerator.cxx
+++ b/Source/cmGlobalGhsMultiGenerator.cxx
@@ -111,7 +111,7 @@
   mf->AddCacheDefinition("CMAKE_MAKE_PROGRAM", gbuild.c_str(),
                          "build program to use", cmStateEnums::INTERNAL, true);
 
-  mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp.c_str());
+  mf->AddDefinition("CMAKE_SYSTEM_VERSION", tsp);
 
   return true;
 }
diff --git a/Source/cmGlobalMSYSMakefileGenerator.cxx b/Source/cmGlobalMSYSMakefileGenerator.cxx
index 7b58389..483d4ab 100644
--- a/Source/cmGlobalMSYSMakefileGenerator.cxx
+++ b/Source/cmGlobalMSYSMakefileGenerator.cxx
@@ -69,9 +69,9 @@
     rc = trc;
   }
   mf->AddDefinition("MSYS", "1");
-  mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str());
-  mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str());
-  mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str());
+  mf->AddDefinition("CMAKE_GENERATOR_CC", gcc);
+  mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx);
+  mf->AddDefinition("CMAKE_GENERATOR_RC", rc);
   this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
 
   if (!mf->IsSet("CMAKE_AR") && !this->CMakeInstance->GetIsInTryCompile() &&
diff --git a/Source/cmGlobalMinGWMakefileGenerator.cxx b/Source/cmGlobalMinGWMakefileGenerator.cxx
index e218b4b..d9fc505 100644
--- a/Source/cmGlobalMinGWMakefileGenerator.cxx
+++ b/Source/cmGlobalMinGWMakefileGenerator.cxx
@@ -44,9 +44,9 @@
   if (!trc.empty()) {
     rc = trc;
   }
-  mf->AddDefinition("CMAKE_GENERATOR_CC", gcc.c_str());
-  mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx.c_str());
-  mf->AddDefinition("CMAKE_GENERATOR_RC", rc.c_str());
+  mf->AddDefinition("CMAKE_GENERATOR_CC", gcc);
+  mf->AddDefinition("CMAKE_GENERATOR_CXX", gxx);
+  mf->AddDefinition("CMAKE_GENERATOR_RC", rc);
   this->cmGlobalUnixMakefileGenerator3::EnableLanguage(l, mf, optional);
 }
 
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 98e8339..7e81a54 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -9,10 +9,11 @@
 #include <algorithm>
 #include <ctype.h>
 #include <iterator>
-#include <memory>
 #include <sstream>
 #include <stdio.h>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmDocumentationEntry.h"
 #include "cmFortranParser.h"
@@ -638,7 +639,9 @@
         (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "GNU") ||
         (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "GNU") ||
         (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "Clang") ||
-        (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang")))) {
+        (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "Clang") ||
+        (mf->GetSafeDefinition("CMAKE_C_COMPILER_ID") == "QCC") ||
+        (mf->GetSafeDefinition("CMAKE_CXX_COMPILER_ID") == "QCC")))) {
     this->UsingGCCOnWindows = true;
   }
 #endif
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 93f5482..35af0e1 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -4,10 +4,11 @@
 
 #include <algorithm>
 #include <functional>
-#include <memory>
 #include <sstream>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmDocumentationEntry.h"
 #include "cmGeneratedFileStream.h"
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 55374a4..4a3cadd 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -445,7 +445,7 @@
     this->DefaultPlatformName = "Tegra-Android";
     this->DefaultPlatformToolset = "Default";
     this->NsightTegraVersion = v;
-    mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v.c_str());
+    mf->AddDefinition("CMAKE_VS_NsightTegra_VERSION", v);
   }
 
   return true;
@@ -659,8 +659,7 @@
   if (!this->cmGlobalVisualStudio8Generator::FindMakeProgram(mf)) {
     return false;
   }
-  mf->AddDefinition("CMAKE_VS_MSBUILD_COMMAND",
-                    this->GetMSBuildCommand().c_str());
+  mf->AddDefinition("CMAKE_VS_MSBUILD_COMMAND", this->GetMSBuildCommand());
   return true;
 }
 
diff --git a/Source/cmGlobalVisualStudio14Generator.cxx b/Source/cmGlobalVisualStudio14Generator.cxx
index 6509b56..cd48474 100644
--- a/Source/cmGlobalVisualStudio14Generator.cxx
+++ b/Source/cmGlobalVisualStudio14Generator.cxx
@@ -182,7 +182,7 @@
     mf->DisplayStatus(e.str(), -1);
   }
   mf->AddDefinition("CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION",
-                    this->WindowsTargetPlatformVersion.c_str());
+                    this->WindowsTargetPlatformVersion);
 }
 
 bool cmGlobalVisualStudio14Generator::SelectWindowsStoreToolset(
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index 8764ee4..8401efb 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -121,8 +121,7 @@
   if (!this->cmGlobalVisualStudioGenerator::FindMakeProgram(mf)) {
     return false;
   }
-  mf->AddDefinition("CMAKE_VS_DEVENV_COMMAND",
-                    this->GetDevEnvCommand().c_str());
+  mf->AddDefinition("CMAKE_VS_DEVENV_COMMAND", this->GetDevEnvCommand());
   return true;
 }
 
@@ -268,7 +267,7 @@
                                                    cmMakefile* mf)
 {
   mf->AddDefinition("CMAKE_VS_INTEL_Fortran_PROJECT_VERSION",
-                    this->GetIntelProjectVersion().c_str());
+                    this->GetIntelProjectVersion());
   return this->cmGlobalVisualStudioGenerator::SetSystemName(s, mf);
 }
 
diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx
index 85ddc85..cc6e421 100644
--- a/Source/cmGlobalVisualStudio8Generator.cxx
+++ b/Source/cmGlobalVisualStudio8Generator.cxx
@@ -54,8 +54,7 @@
 void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf)
 {
   if (this->TargetsWindowsCE()) {
-    mf->AddDefinition("CMAKE_VS_WINCE_VERSION",
-                      this->WindowsCEVersion.c_str());
+    mf->AddDefinition("CMAKE_VS_WINCE_VERSION", this->WindowsCEVersion);
   }
 }
 
diff --git a/Source/cmGlobalVisualStudioGenerator.cxx b/Source/cmGlobalVisualStudioGenerator.cxx
index cd0355f..ba541a9 100644
--- a/Source/cmGlobalVisualStudioGenerator.cxx
+++ b/Source/cmGlobalVisualStudioGenerator.cxx
@@ -57,7 +57,7 @@
   std::vector<std::string> const& lang, cmMakefile* mf, bool optional)
 {
   mf->AddDefinition("CMAKE_VS_PLATFORM_NAME_DEFAULT",
-                    this->DefaultPlatformName.c_str());
+                    this->DefaultPlatformName);
   this->cmGlobalGenerator::EnableLanguage(lang, mf, optional);
 }
 
@@ -69,7 +69,7 @@
   } else if (this->GetPlatformName() == "Itanium") {
     mf->AddDefinition("CMAKE_FORCE_IA64", "TRUE");
   }
-  mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName().c_str());
+  mf->AddDefinition("CMAKE_VS_PLATFORM_NAME", this->GetPlatformName());
   return this->cmGlobalGenerator::SetGeneratorPlatform(p, mf);
 }
 
@@ -488,7 +488,7 @@
   // directly instead of needing a helper module to do it, so we
   // do not actually need to put CMAKE_MAKE_PROGRAM into the cache.
   if (cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
-    mf->AddDefinition("CMAKE_MAKE_PROGRAM", this->GetVSMakeProgram().c_str());
+    mf->AddDefinition("CMAKE_MAKE_PROGRAM", this->GetVSMakeProgram());
   }
   return true;
 }
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 78e8f30..8f4ae62 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -5,11 +5,12 @@
 #include "cmsys/RegularExpression.hxx"
 #include <assert.h>
 #include <iomanip>
-#include <memory>
 #include <sstream>
 #include <stdio.h>
 #include <string.h>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmComputeLinkInformation.h"
 #include "cmCustomCommand.h"
@@ -240,8 +241,7 @@
   // directly instead of needing a helper module to do it, so we
   // do not actually need to put CMAKE_MAKE_PROGRAM into the cache.
   if (cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM"))) {
-    mf->AddDefinition("CMAKE_MAKE_PROGRAM",
-                      this->GetXcodeBuildCommand().c_str());
+    mf->AddDefinition("CMAKE_MAKE_PROGRAM", this->GetXcodeBuildCommand());
   }
   return true;
 }
@@ -282,8 +282,7 @@
   }
   this->GeneratorToolset = ts;
   if (!this->GeneratorToolset.empty()) {
-    mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET",
-                      this->GeneratorToolset.c_str());
+    mf->AddDefinition("CMAKE_XCODE_PLATFORM_TOOLSET", this->GeneratorToolset);
   }
   return true;
 }
@@ -292,7 +291,7 @@
   std::vector<std::string> const& lang, cmMakefile* mf, bool optional)
 {
   mf->AddDefinition("XCODE", "1");
-  mf->AddDefinition("XCODE_VERSION", this->VersionString.c_str());
+  mf->AddDefinition("XCODE_VERSION", this->VersionString);
   if (!mf->GetDefinition("CMAKE_CONFIGURATION_TYPES")) {
     mf->AddCacheDefinition(
       "CMAKE_CONFIGURATION_TYPES", "Debug;Release;MinSizeRel;RelWithDebInfo",
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 6f32861..385022c 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -2,6 +2,8 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmIfCommand.h"
 
+#include "cm_memory.hxx"
+
 #include "cmConditionEvaluator.h"
 #include "cmExecutionStatus.h"
 #include "cmExpandedCommandArgument.h"
@@ -11,7 +13,8 @@
 #include "cmSystemTools.h"
 #include "cmake.h"
 
-#include <memory>
+#include <string>
+#include <utility>
 
 static std::string cmIfCommandError(
   std::vector<cmExpandedCommandArgument> const& args)
@@ -45,7 +48,7 @@
       }
 
       // execute the functions for the true parts of the if statement
-      cmExecutionStatus status;
+      cmExecutionStatus status(mf);
       int scopeDepth = 0;
       for (cmListFileFunction const& func : this->Functions) {
         // keep track of scope depth
@@ -174,19 +177,19 @@
 }
 
 //=========================================================================
-bool cmIfCommand::InvokeInitialPass(
-  const std::vector<cmListFileArgument>& args, cmExecutionStatus&)
+bool cmIfCommand(std::vector<cmListFileArgument> const& args,
+                 cmExecutionStatus& inStatus)
 {
+  cmMakefile& makefile = inStatus.GetMakefile();
   std::string errorString;
 
   std::vector<cmExpandedCommandArgument> expandedArguments;
-  this->Makefile->ExpandArguments(args, expandedArguments);
+  makefile.ExpandArguments(args, expandedArguments);
 
   MessageType status;
 
   cmConditionEvaluator conditionEvaluator(
-    *(this->Makefile), this->Makefile->GetExecutionContext(),
-    this->Makefile->GetBacktrace());
+    makefile, makefile.GetExecutionContext(), makefile.GetBacktrace());
 
   bool isTrue =
     conditionEvaluator.IsTrue(expandedArguments, errorString, status);
@@ -195,22 +198,24 @@
     std::string err = "if " + cmIfCommandError(expandedArguments);
     err += errorString;
     if (status == MessageType::FATAL_ERROR) {
-      this->Makefile->IssueMessage(MessageType::FATAL_ERROR, err);
+      makefile.IssueMessage(MessageType::FATAL_ERROR, err);
       cmSystemTools::SetFatalErrorOccured();
       return true;
     }
-    this->Makefile->IssueMessage(status, err);
+    makefile.IssueMessage(status, err);
   }
 
-  cmIfFunctionBlocker* f = new cmIfFunctionBlocker();
-  // if is isn't true block the commands
-  f->ScopeDepth = 1;
-  f->IsBlocking = !isTrue;
-  if (isTrue) {
-    f->HasRun = true;
+  {
+    auto fb = cm::make_unique<cmIfFunctionBlocker>();
+    // if is isn't true block the commands
+    fb->ScopeDepth = 1;
+    fb->IsBlocking = !isTrue;
+    if (isTrue) {
+      fb->HasRun = true;
+    }
+    fb->Args = args;
+    makefile.AddFunctionBlocker(std::move(fb));
   }
-  f->Args = args;
-  this->Makefile->AddFunctionBlocker(f);
 
   return true;
 }
diff --git a/Source/cmIfCommand.h b/Source/cmIfCommand.h
index d34ed02..775e609 100644
--- a/Source/cmIfCommand.h
+++ b/Source/cmIfCommand.h
@@ -5,15 +5,12 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include <string>
 #include <vector>
 
-#include "cmCommand.h"
 #include "cmFunctionBlocker.h"
 #include "cmListFileCache.h"
 
 class cmExecutionStatus;
-class cmExpandedCommandArgument;
 class cmMakefile;
 
 class cmIfFunctionBlocker : public cmFunctionBlocker
@@ -32,34 +29,7 @@
 };
 
 /// Starts an if block
-class cmIfCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  cmCommand* Clone() override { return new cmIfCommand; }
-
-  /**
-   * This overrides the default InvokeInitialPass implementation.
-   * It records the arguments before expansion.
-   */
-  bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
-                         cmExecutionStatus&) override;
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const&,
-                   cmExecutionStatus&) override
-  {
-    return false;
-  }
-
-  // Filter the given variable definition based on policy CMP0054.
-  static const char* GetDefinitionIfUnquoted(
-    const cmMakefile* mf, cmExpandedCommandArgument const& argument);
-};
+bool cmIfCommand(std::vector<cmListFileArgument> const& args,
+                 cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmIncludeCommand.h b/Source/cmIncludeCommand.h
index 3b843b2..94d3fbd 100644
--- a/Source/cmIncludeCommand.h
+++ b/Source/cmIncludeCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmIncludeCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmIncludeCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmIncludeDirectoryCommand.h b/Source/cmIncludeDirectoryCommand.h
index 01d98db..4df94eb 100644
--- a/Source/cmIncludeDirectoryCommand.h
+++ b/Source/cmIncludeDirectoryCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmIncludeDirectoryCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmIncludeDirectoryCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmIncludeExternalMSProjectCommand.h b/Source/cmIncludeExternalMSProjectCommand.h
index 945acdc..9f76576 100644
--- a/Source/cmIncludeExternalMSProjectCommand.h
+++ b/Source/cmIncludeExternalMSProjectCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -25,7 +27,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmIncludeExternalMSProjectCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmIncludeExternalMSProjectCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmIncludeGuardCommand.cxx b/Source/cmIncludeGuardCommand.cxx
index 505b07c..3b126b0 100644
--- a/Source/cmIncludeGuardCommand.cxx
+++ b/Source/cmIncludeGuardCommand.cxx
@@ -85,7 +85,7 @@
         status.SetReturnInvoked();
         return true;
       }
-      mf->AddDefinition(includeGuardVar, true);
+      mf->AddDefinitionBool(includeGuardVar, true);
       break;
     case DIRECTORY:
       if (CheckIncludeGuardIsSet(mf, includeGuardVar)) {
diff --git a/Source/cmIncludeGuardCommand.h b/Source/cmIncludeGuardCommand.h
index eaad9b8..4306c4c 100644
--- a/Source/cmIncludeGuardCommand.h
+++ b/Source/cmIncludeGuardCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmIncludeGuardCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmIncludeGuardCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmIncludeRegularExpressionCommand.h b/Source/cmIncludeRegularExpressionCommand.h
index 8da991d..1723c8b 100644
--- a/Source/cmIncludeRegularExpressionCommand.h
+++ b/Source/cmIncludeRegularExpressionCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmIncludeRegularExpressionCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmIncludeRegularExpressionCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index dba4bbb..3b0659c 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -389,10 +389,6 @@
     return true;
   }
 
-  // Check whether this is a DLL platform.
-  bool dll_platform =
-    !this->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty();
-
   for (std::string const& tgt : targetList) {
 
     if (this->Makefile->IsAlias(tgt)) {
@@ -472,7 +468,7 @@
         // Shared libraries are handled differently on DLL and non-DLL
         // platforms.  All windows platforms are DLL platforms including
         // cygwin.  Currently no other platform is a DLL platform.
-        if (dll_platform) {
+        if (target.IsDLLPlatform()) {
           // When in namelink only mode skip all libraries on Windows.
           if (namelinkMode == cmInstallTargetGenerator::NamelinkModeOnly) {
             continue;
@@ -641,7 +637,8 @@
         // On DLL platforms an executable may also have an import
         // library.  Install it to the archive destination if it
         // exists.
-        if (dll_platform && !archiveArgs.GetDestination().empty() &&
+        if ((target.IsDLLPlatform() || target.IsAIX()) &&
+            !archiveArgs.GetDestination().empty() &&
             target.IsExecutableWithExports()) {
           // The import library uses the ARCHIVE properties.
           archiveGenerator = CreateInstallTargetGenerator(
diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h
index 202c438..28bf443 100644
--- a/Source/cmInstallCommand.h
+++ b/Source/cmInstallCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -25,7 +27,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmInstallCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmInstallCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmInstallFilesCommand.cxx b/Source/cmInstallFilesCommand.cxx
index efbcb67..4522669 100644
--- a/Source/cmInstallFilesCommand.cxx
+++ b/Source/cmInstallFilesCommand.cxx
@@ -2,7 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmInstallFilesCommand.h"
 
-#include "cmAlgorithms.h"
 #include "cmGeneratorExpression.h"
 #include "cmGlobalGenerator.h"
 #include "cmInstallFilesGenerator.h"
@@ -13,7 +12,13 @@
 
 class cmExecutionStatus;
 
-// cmExecutableCommand
+static std::string FindInstallSource(cmMakefile& makefile, const char* name);
+static void CreateInstallGenerator(cmMakefile& makefile,
+                                   std::string const& dest,
+                                   std::vector<std::string> const& files);
+static void FinalAction(cmMakefile& makefile, std::string const& dest,
+                        std::vector<std::string> const& args);
+
 bool cmInstallFilesCommand::InitialPass(std::vector<std::string> const& args,
                                         cmExecutionStatus&)
 {
@@ -25,18 +30,20 @@
   // Enable the install target.
   this->Makefile->GetGlobalGenerator()->EnableInstallTarget();
 
-  this->Destination = args[0];
+  std::string const& dest = args[0];
 
   if ((args.size() > 1) && (args[1] == "FILES")) {
-    this->IsFilesForm = true;
+    std::vector<std::string> files;
     for (std::string const& arg : cmMakeRange(args).advance(2)) {
       // Find the source location for each file listed.
-      this->Files.push_back(this->FindInstallSource(arg.c_str()));
+      files.push_back(FindInstallSource(*this->Makefile, arg.c_str()));
     }
-    this->CreateInstallGenerator();
+    CreateInstallGenerator(*this->Makefile, dest, files);
   } else {
-    this->IsFilesForm = false;
-    cmAppend(this->FinalArgs, args.begin() + 1, args.end());
+    std::vector<std::string> finalArgs(args.begin() + 1, args.end());
+    this->Makefile->AddFinalAction([dest, finalArgs](cmMakefile& makefile) {
+      FinalAction(makefile, dest, finalArgs);
+    });
   }
 
   this->Makefile->GetGlobalGenerator()->AddInstallComponent(
@@ -45,23 +52,20 @@
   return true;
 }
 
-void cmInstallFilesCommand::FinalPass()
+static void FinalAction(cmMakefile& makefile, std::string const& dest,
+                        std::vector<std::string> const& args)
 {
-  // No final pass for "FILES" form of arguments.
-  if (this->IsFilesForm) {
-    return;
-  }
-
   std::string testf;
-  std::string const& ext = this->FinalArgs[0];
+  std::string const& ext = args[0];
+  std::vector<std::string> installFiles;
 
   // two different options
-  if (this->FinalArgs.size() > 1) {
+  if (args.size() > 1) {
     // now put the files into the list
-    std::vector<std::string>::iterator s = this->FinalArgs.begin();
+    std::vector<std::string>::const_iterator s = args.begin();
     ++s;
     // for each argument, get the files
-    for (; s != this->FinalArgs.end(); ++s) {
+    for (; s != args.end(); ++s) {
       // replace any variables
       std::string const& temps = *s;
       if (!cmSystemTools::GetFilenamePath(temps).empty()) {
@@ -72,30 +76,31 @@
       }
 
       // add to the result
-      this->Files.push_back(this->FindInstallSource(testf.c_str()));
+      installFiles.push_back(FindInstallSource(makefile, testf.c_str()));
     }
   } else // reg exp list
   {
     std::vector<std::string> files;
-    std::string const& regex = this->FinalArgs[0];
-    cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(), regex,
-                        files);
+    std::string const& regex = args[0];
+    cmSystemTools::Glob(makefile.GetCurrentSourceDirectory(), regex, files);
 
     std::vector<std::string>::iterator s = files.begin();
     // for each argument, get the files
     for (; s != files.end(); ++s) {
-      this->Files.push_back(this->FindInstallSource(s->c_str()));
+      installFiles.push_back(FindInstallSource(makefile, s->c_str()));
     }
   }
 
-  this->CreateInstallGenerator();
+  CreateInstallGenerator(makefile, dest, installFiles);
 }
 
-void cmInstallFilesCommand::CreateInstallGenerator() const
+static void CreateInstallGenerator(cmMakefile& makefile,
+                                   std::string const& dest,
+                                   std::vector<std::string> const& files)
 {
   // Construct the destination.  This command always installs under
   // the prefix.  We skip the leading slash given by the user.
-  std::string destination = this->Destination.substr(1);
+  std::string destination = dest.substr(1);
   cmSystemTools::ConvertToUnixSlashes(destination);
   if (destination.empty()) {
     destination = ".";
@@ -106,12 +111,12 @@
   const char* no_rename = "";
   bool no_exclude_from_all = false;
   std::string no_component =
-    this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
+    makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
   std::vector<std::string> no_configurations;
   cmInstallGenerator::MessageLevel message =
-    cmInstallGenerator::SelectMessageLevel(this->Makefile);
-  this->Makefile->AddInstallGenerator(new cmInstallFilesGenerator(
-    this->Files, destination.c_str(), false, no_permissions, no_configurations,
+    cmInstallGenerator::SelectMessageLevel(&makefile);
+  makefile.AddInstallGenerator(new cmInstallFilesGenerator(
+    files, destination.c_str(), false, no_permissions, no_configurations,
     no_component.c_str(), message, no_exclude_from_all, no_rename));
 }
 
@@ -121,7 +126,7 @@
  * present in the build tree.  If a full path is given, it is just
  * returned.
  */
-std::string cmInstallFilesCommand::FindInstallSource(const char* name) const
+static std::string FindInstallSource(cmMakefile& makefile, const char* name)
 {
   if (cmSystemTools::FileIsFullPath(name) ||
       cmGeneratorExpression::Find(name) == 0) {
@@ -130,10 +135,10 @@
   }
 
   // This is a relative path.
-  std::string tb = this->Makefile->GetCurrentBinaryDirectory();
+  std::string tb = makefile.GetCurrentBinaryDirectory();
   tb += "/";
   tb += name;
-  std::string ts = this->Makefile->GetCurrentSourceDirectory();
+  std::string ts = makefile.GetCurrentSourceDirectory();
   ts += "/";
   ts += name;
 
diff --git a/Source/cmInstallFilesCommand.h b/Source/cmInstallFilesCommand.h
index a52f45e..f9b84fd 100644
--- a/Source/cmInstallFilesCommand.h
+++ b/Source/cmInstallFilesCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmInstallFilesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmInstallFilesCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
@@ -32,25 +37,6 @@
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
-
-  /**
-   * This is called at the end after all the information
-   * specified by the command is accumulated. Most commands do
-   * not implement this method.  At this point, reading and
-   * writing to the cache can be done.
-   */
-  void FinalPass() override;
-  bool HasFinalPass() const override { return !this->IsFilesForm; }
-
-protected:
-  void CreateInstallGenerator() const;
-  std::string FindInstallSource(const char* name) const;
-
-private:
-  std::vector<std::string> FinalArgs;
-  bool IsFilesForm = false;
-  std::string Destination;
-  std::vector<std::string> Files;
 };
 
 #endif
diff --git a/Source/cmInstallProgramsCommand.cxx b/Source/cmInstallProgramsCommand.cxx
index a58f875..6ec02e7 100644
--- a/Source/cmInstallProgramsCommand.cxx
+++ b/Source/cmInstallProgramsCommand.cxx
@@ -2,7 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmInstallProgramsCommand.h"
 
-#include "cmAlgorithms.h"
 #include "cmGeneratorExpression.h"
 #include "cmGlobalGenerator.h"
 #include "cmInstallFilesGenerator.h"
@@ -12,6 +11,10 @@
 
 class cmExecutionStatus;
 
+static void FinalAction(cmMakefile& makefile, std::string const& dest,
+                        std::vector<std::string> const& args);
+static std::string FindInstallSource(cmMakefile& makefile, const char* name);
+
 // cmExecutableCommand
 bool cmInstallProgramsCommand::InitialPass(
   std::vector<std::string> const& args, cmExecutionStatus&)
@@ -24,51 +27,55 @@
   // Enable the install target.
   this->Makefile->GetGlobalGenerator()->EnableInstallTarget();
 
-  this->Destination = args[0];
-
-  cmAppend(this->FinalArgs, args.begin() + 1, args.end());
-
   this->Makefile->GetGlobalGenerator()->AddInstallComponent(
     this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME"));
 
+  std::string const& dest = args[0];
+  std::vector<std::string> const finalArgs(args.begin() + 1, args.end());
+  this->Makefile->AddFinalAction([dest, finalArgs](cmMakefile& makefile) {
+    FinalAction(makefile, dest, finalArgs);
+  });
   return true;
 }
 
-void cmInstallProgramsCommand::FinalPass()
+static void FinalAction(cmMakefile& makefile, std::string const& dest,
+                        std::vector<std::string> const& args)
 {
   bool files_mode = false;
-  if (!this->FinalArgs.empty() && this->FinalArgs[0] == "FILES") {
+  if (!args.empty() && args[0] == "FILES") {
     files_mode = true;
   }
 
+  std::vector<std::string> files;
+
   // two different options
-  if (this->FinalArgs.size() > 1 || files_mode) {
+  if (args.size() > 1 || files_mode) {
     // for each argument, get the programs
-    std::vector<std::string>::iterator s = this->FinalArgs.begin();
+    std::vector<std::string>::const_iterator s = args.begin();
     if (files_mode) {
       // Skip the FILES argument in files mode.
       ++s;
     }
-    for (; s != this->FinalArgs.end(); ++s) {
+    for (; s != args.end(); ++s) {
       // add to the result
-      this->Files.push_back(this->FindInstallSource(s->c_str()));
+      files.push_back(FindInstallSource(makefile, s->c_str()));
     }
   } else // reg exp list
   {
     std::vector<std::string> programs;
-    cmSystemTools::Glob(this->Makefile->GetCurrentSourceDirectory(),
-                        this->FinalArgs[0], programs);
+    cmSystemTools::Glob(makefile.GetCurrentSourceDirectory(), args[0],
+                        programs);
 
     std::vector<std::string>::iterator s = programs.begin();
     // for each argument, get the programs
     for (; s != programs.end(); ++s) {
-      this->Files.push_back(this->FindInstallSource(s->c_str()));
+      files.push_back(FindInstallSource(makefile, s->c_str()));
     }
   }
 
   // Construct the destination.  This command always installs under
   // the prefix.  We skip the leading slash given by the user.
-  std::string destination = this->Destination.substr(1);
+  std::string destination = dest.substr(1);
   cmSystemTools::ConvertToUnixSlashes(destination);
   if (destination.empty()) {
     destination = ".";
@@ -79,12 +86,12 @@
   const char* no_rename = "";
   bool no_exclude_from_all = false;
   std::string no_component =
-    this->Makefile->GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
+    makefile.GetSafeDefinition("CMAKE_INSTALL_DEFAULT_COMPONENT_NAME");
   std::vector<std::string> no_configurations;
   cmInstallGenerator::MessageLevel message =
-    cmInstallGenerator::SelectMessageLevel(this->Makefile);
-  this->Makefile->AddInstallGenerator(new cmInstallFilesGenerator(
-    this->Files, destination.c_str(), true, no_permissions, no_configurations,
+    cmInstallGenerator::SelectMessageLevel(&makefile);
+  makefile.AddInstallGenerator(new cmInstallFilesGenerator(
+    files, destination.c_str(), true, no_permissions, no_configurations,
     no_component.c_str(), message, no_exclude_from_all, no_rename));
 }
 
@@ -94,7 +101,7 @@
  * present in the build tree.  If a full path is given, it is just
  * returned.
  */
-std::string cmInstallProgramsCommand::FindInstallSource(const char* name) const
+static std::string FindInstallSource(cmMakefile& makefile, const char* name)
 {
   if (cmSystemTools::FileIsFullPath(name) ||
       cmGeneratorExpression::Find(name) == 0) {
@@ -103,10 +110,10 @@
   }
 
   // This is a relative path.
-  std::string tb = this->Makefile->GetCurrentBinaryDirectory();
+  std::string tb = makefile.GetCurrentBinaryDirectory();
   tb += "/";
   tb += name;
-  std::string ts = this->Makefile->GetCurrentSourceDirectory();
+  std::string ts = makefile.GetCurrentSourceDirectory();
   ts += "/";
   ts += name;
 
diff --git a/Source/cmInstallProgramsCommand.h b/Source/cmInstallProgramsCommand.h
index 5c705eb..ccd621d 100644
--- a/Source/cmInstallProgramsCommand.h
+++ b/Source/cmInstallProgramsCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmInstallProgramsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmInstallProgramsCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
@@ -32,24 +37,6 @@
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
-
-  /**
-   * This is called at the end after all the information
-   * specified by the command is accumulated. Most commands do
-   * not implement this method.  At this point, reading and
-   * writing to the cache can be done.
-   */
-  void FinalPass() override;
-
-  bool HasFinalPass() const override { return true; }
-
-protected:
-  std::string FindInstallSource(const char* name) const;
-
-private:
-  std::vector<std::string> FinalArgs;
-  std::string Destination;
-  std::vector<std::string> Files;
 };
 
 #endif
diff --git a/Source/cmInstallTargetGenerator.cxx b/Source/cmInstallTargetGenerator.cxx
index d891ad8..a61239e 100644
--- a/Source/cmInstallTargetGenerator.cxx
+++ b/Source/cmInstallTargetGenerator.cxx
@@ -767,12 +767,18 @@
         this->IssueCMP0095Warning(newRpath);
         CM_FALLTHROUGH;
       case cmPolicies::OLD:
-        os << indent << "     NEW_RPATH \"" << newRpath << "\")\n";
+        os << indent << "     NEW_RPATH \"" << newRpath << "\"";
         break;
       default:
-        os << indent << "     NEW_RPATH " << escapedNewRpath << ")\n";
+        os << indent << "     NEW_RPATH " << escapedNewRpath;
         break;
     }
+
+    if (this->Target->GetPropertyAsBool("INSTALL_REMOVE_ENVIRONMENT_RPATH")) {
+      os << "\n" << indent << "     INSTALL_REMOVE_ENVIRONMENT_RPATH)\n";
+    } else {
+      os << indent << ")\n";
+    }
   }
 }
 
diff --git a/Source/cmInstallTargetsCommand.h b/Source/cmInstallTargetsCommand.h
index 9950fb7..55e69ba 100644
--- a/Source/cmInstallTargetsCommand.h
+++ b/Source/cmInstallTargetsCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -25,7 +27,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmInstallTargetsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmInstallTargetsCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmJsonObjects.cxx b/Source/cmJsonObjects.cxx
index 505188f..2423faf 100644
--- a/Source/cmJsonObjects.cxx
+++ b/Source/cmJsonObjects.cxx
@@ -516,9 +516,11 @@
     Json::Value artifacts = Json::arrayValue;
     artifacts.append(
       target->GetFullPath(config, cmStateEnums::RuntimeBinaryArtifact));
-    if (target->IsDLLPlatform()) {
+    if (target->HasImportLibrary(config)) {
       artifacts.append(
         target->GetFullPath(config, cmStateEnums::ImportLibraryArtifact));
+    }
+    if (target->IsDLLPlatform()) {
       const cmGeneratorTarget::OutputInfo* output =
         target->GetOutputInfo(config);
       if (output && !output->PdbDir.empty()) {
diff --git a/Source/cmLinkDirectoriesCommand.h b/Source/cmLinkDirectoriesCommand.h
index ae4fb7f..1a439de 100644
--- a/Source/cmLinkDirectoriesCommand.h
+++ b/Source/cmLinkDirectoriesCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -26,7 +28,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmLinkDirectoriesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmLinkDirectoriesCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index 5b635b5..6450c62 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -58,6 +58,9 @@
 {
   // Libraries listed in the interface.
   std::vector<cmLinkItem> Libraries;
+
+  // Whether the list depends on a genex referencing the head target.
+  bool HadHeadSensitiveCondition = false;
 };
 
 struct cmLinkInterface : public cmLinkInterfaceLibraries
@@ -84,7 +87,6 @@
   bool LibrariesDone = false;
   bool AllDone = false;
   bool Exists = false;
-  bool HadHeadSensitiveCondition = false;
   const char* ExplicitLibraries = nullptr;
 };
 
diff --git a/Source/cmLinkLibrariesCommand.h b/Source/cmLinkLibrariesCommand.h
index af25fba..484ab0a 100644
--- a/Source/cmLinkLibrariesCommand.h
+++ b/Source/cmLinkLibrariesCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -25,7 +27,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmLinkLibrariesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmLinkLibrariesCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmLinkLineComputer.cxx b/Source/cmLinkLineComputer.cxx
index 469faca..8746b35 100644
--- a/Source/cmLinkLineComputer.cxx
+++ b/Source/cmLinkLineComputer.cxx
@@ -110,8 +110,7 @@
       if (target->GetType() == cmStateEnums::STATIC_LIBRARY ||
           target->GetType() == cmStateEnums::SHARED_LIBRARY) {
         cmStateEnums::ArtifactType type = cmStateEnums::RuntimeBinaryArtifact;
-        if (target->GetType() == cmStateEnums::SHARED_LIBRARY &&
-            target->IsDLLPlatform()) {
+        if (target->HasImportLibrary(cli.GetConfig())) {
           type = cmStateEnums::ImportLibraryArtifact;
         }
 
diff --git a/Source/cmListCommand.cxx b/Source/cmListCommand.cxx
index e9a4a6f..d024256 100644
--- a/Source/cmListCommand.cxx
+++ b/Source/cmListCommand.cxx
@@ -7,7 +7,6 @@
 #include <assert.h>
 #include <functional>
 #include <iterator>
-#include <memory>
 #include <set>
 #include <sstream>
 #include <stdexcept>
@@ -16,6 +15,8 @@
 #include <utility>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmGeneratorExpression.h"
 #include "cmMakefile.h"
@@ -221,7 +222,7 @@
     value += varArgsExpanded[item];
   }
 
-  this->Makefile->AddDefinition(variableName, value.c_str());
+  this->Makefile->AddDefinition(variableName, value);
   return true;
 }
 
@@ -245,7 +246,7 @@
     std::string::size_type(listString.empty() || args.empty());
   listString += &";"[offset] + cmJoin(cmMakeRange(args).advance(2), ";");
 
-  this->Makefile->AddDefinition(listName, listString.c_str());
+  this->Makefile->AddDefinition(listName, listString);
   return true;
 }
 
@@ -270,7 +271,7 @@
   listString.insert(0,
                     cmJoin(cmMakeRange(args).advance(2), ";") + &";"[offset]);
 
-  this->Makefile->AddDefinition(listName, listString.c_str());
+  this->Makefile->AddDefinition(listName, listString);
   return true;
 }
 
@@ -298,7 +299,7 @@
       // Ok, assign elements to be removed to the given variables
       for (; !varArgsExpanded.empty() && ai != args.cend(); ++ai) {
         assert(!ai->empty());
-        this->Makefile->AddDefinition(*ai, varArgsExpanded.back().c_str());
+        this->Makefile->AddDefinition(*ai, varArgsExpanded.back());
         varArgsExpanded.pop_back();
       }
       // Undefine the rest variables if the list gets empty earlier...
@@ -307,8 +308,7 @@
       }
     }
 
-    this->Makefile->AddDefinition(listName,
-                                  cmJoin(varArgsExpanded, ";").c_str());
+    this->Makefile->AddDefinition(listName, cmJoin(varArgsExpanded, ";"));
 
   } else if (ai !=
              args.cend()) { // The list is empty, but some args were given
@@ -346,7 +346,7 @@
       auto vi = varArgsExpanded.begin();
       for (; vi != varArgsExpanded.end() && ai != args.cend(); ++ai, ++vi) {
         assert(!ai->empty());
-        this->Makefile->AddDefinition(*ai, vi->c_str());
+        this->Makefile->AddDefinition(*ai, *vi);
       }
       varArgsExpanded.erase(varArgsExpanded.begin(), vi);
       // Undefine the rest variables if the list gets empty earlier...
@@ -355,8 +355,7 @@
       }
     }
 
-    this->Makefile->AddDefinition(listName,
-                                  cmJoin(varArgsExpanded, ";").c_str());
+    this->Makefile->AddDefinition(listName, cmJoin(varArgsExpanded, ";"));
 
   } else if (ai !=
              args.cend()) { // The list is empty, but some args were given
@@ -390,7 +389,7 @@
   if (it != varArgsExpanded.end()) {
     std::ostringstream indexStream;
     indexStream << std::distance(varArgsExpanded.begin(), it);
-    this->Makefile->AddDefinition(variableName, indexStream.str().c_str());
+    this->Makefile->AddDefinition(variableName, indexStream.str());
     return true;
   }
 
@@ -436,7 +435,7 @@
                          args.end());
 
   std::string value = cmJoin(varArgsExpanded, ";");
-  this->Makefile->AddDefinition(listName, value.c_str());
+  this->Makefile->AddDefinition(listName, value);
   return true;
 }
 
@@ -464,7 +463,7 @@
   std::string value =
     cmJoin(cmMakeRange(varArgsExpanded.begin(), varArgsExpanded.end()), glue);
 
-  this->Makefile->AddDefinition(variableName, value.c_str());
+  this->Makefile->AddDefinition(variableName, value);
   return true;
 }
 
@@ -493,7 +492,7 @@
     cmRemoveMatching(varArgsExpanded, cmMakeRange(remBegin, remEnd));
   std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
   std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
-  this->Makefile->AddDefinition(listName, value.c_str());
+  this->Makefile->AddDefinition(listName, value);
   return true;
 }
 
@@ -514,7 +513,7 @@
 
   std::string value = cmJoin(cmReverseRange(varArgsExpanded), ";");
 
-  this->Makefile->AddDefinition(listName, value.c_str());
+  this->Makefile->AddDefinition(listName, value);
   return true;
 }
 
@@ -539,7 +538,7 @@
   std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
   std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
 
-  this->Makefile->AddDefinition(listName, value.c_str());
+  this->Makefile->AddDefinition(listName, value);
   return true;
 }
 
@@ -1090,7 +1089,7 @@
   }
 
   this->Makefile->AddDefinition(command.OutputName,
-                                cmJoin(varArgsExpanded, ";").c_str());
+                                cmJoin(varArgsExpanded, ";"));
 
   return true;
 }
@@ -1299,7 +1298,7 @@
   }
 
   std::string value = cmJoin(varArgsExpanded, ";");
-  this->Makefile->AddDefinition(listName, value.c_str());
+  this->Makefile->AddDefinition(listName, value);
   return true;
 }
 
@@ -1348,7 +1347,7 @@
     : size_type(start + length);
   std::vector<std::string> sublist(varArgsExpanded.begin() + start,
                                    varArgsExpanded.begin() + end);
-  this->Makefile->AddDefinition(variableName, cmJoin(sublist, ";").c_str());
+  this->Makefile->AddDefinition(variableName, cmJoin(sublist, ";"));
   return true;
 }
 
@@ -1405,7 +1404,7 @@
   std::vector<std::string>::const_iterator argsBegin = varArgsExpanded.begin();
   std::string value = cmJoin(cmMakeRange(argsBegin, argsEnd), ";");
 
-  this->Makefile->AddDefinition(listName, value.c_str());
+  this->Makefile->AddDefinition(listName, value);
   return true;
 }
 
@@ -1499,6 +1498,6 @@
     std::remove_if(argsBegin, argsEnd, MatchesRegex(regex, includeMatches));
 
   std::string value = cmJoin(cmMakeRange(argsBegin, newArgsEnd), ";");
-  this->Makefile->AddDefinition(listName, value.c_str());
+  this->Makefile->AddDefinition(listName, value);
   return true;
 }
diff --git a/Source/cmListCommand.h b/Source/cmListCommand.h
index ea3d643..70c7f4e 100644
--- a/Source/cmListCommand.h
+++ b/Source/cmListCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -22,7 +24,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmListCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmListCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmLoadCacheCommand.cxx b/Source/cmLoadCacheCommand.cxx
index b1fee8d..3fd7343 100644
--- a/Source/cmLoadCacheCommand.cxx
+++ b/Source/cmLoadCacheCommand.cxx
@@ -153,7 +153,7 @@
       // prefix.
       var = this->Prefix + var;
       if (!value.empty()) {
-        this->Makefile->AddDefinition(var, value.c_str());
+        this->Makefile->AddDefinition(var, value);
       } else {
         this->Makefile->RemoveDefinition(var);
       }
diff --git a/Source/cmLoadCacheCommand.h b/Source/cmLoadCacheCommand.h
index e0f6e4f..45e52f0 100644
--- a/Source/cmLoadCacheCommand.h
+++ b/Source/cmLoadCacheCommand.h
@@ -9,6 +9,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmLoadCacheCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmLoadCacheCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmLoadCommandCommand.cxx b/Source/cmLoadCommandCommand.cxx
index 69751b6..5ae660a 100644
--- a/Source/cmLoadCommandCommand.cxx
+++ b/Source/cmLoadCommandCommand.cxx
@@ -3,10 +3,14 @@
 #include "cmLoadCommandCommand.h"
 
 #include <signal.h>
+
 #include <sstream>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <utility>
+
+#include "cm_memory.hxx"
 
 #include "cmCPluginAPI.cxx"
 #include "cmCPluginAPI.h"
@@ -21,30 +25,98 @@
 #  include <malloc.h> /* for malloc/free on QNX */
 #endif
 
-extern "C" void TrapsForSignalsCFunction(int sig);
+namespace {
+
+const char* LastName = nullptr;
+
+extern "C" void TrapsForSignals(int sig)
+{
+  fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n",
+          LastName, sig);
+}
+
+struct SignalHandlerGuard
+{
+  explicit SignalHandlerGuard(const char* name)
+  {
+    LastName = name != nullptr ? name : "????";
+
+    signal(SIGSEGV, TrapsForSignals);
+#ifdef SIGBUS
+    signal(SIGBUS, TrapsForSignals);
+#endif
+    signal(SIGILL, TrapsForSignals);
+  }
+
+  ~SignalHandlerGuard()
+  {
+    signal(SIGSEGV, nullptr);
+#ifdef SIGBUS
+    signal(SIGBUS, nullptr);
+#endif
+    signal(SIGILL, nullptr);
+  }
+
+  SignalHandlerGuard(SignalHandlerGuard const&) = delete;
+  SignalHandlerGuard& operator=(SignalHandlerGuard const&) = delete;
+};
+
+struct LoadedCommandImpl : cmLoadedCommandInfo
+{
+  explicit LoadedCommandImpl(CM_INIT_FUNCTION init)
+    : cmLoadedCommandInfo{ 0,       0,       &cmStaticCAPI, 0,
+                           nullptr, nullptr, nullptr,       nullptr,
+                           nullptr, nullptr, nullptr,       nullptr }
+  {
+    init(this);
+  }
+
+  ~LoadedCommandImpl()
+  {
+    if (this->Destructor) {
+      SignalHandlerGuard guard(this->Name);
+      this->Destructor(this);
+    }
+    if (this->Error != nullptr) {
+      free(this->Error);
+    }
+  }
+
+  LoadedCommandImpl(LoadedCommandImpl const&) = delete;
+  LoadedCommandImpl& operator=(LoadedCommandImpl const&) = delete;
+
+  int DoInitialPass(cmMakefile* mf, int argc, char* argv[])
+  {
+    SignalHandlerGuard guard(this->Name);
+    return this->InitialPass(this, mf, argc, argv);
+  }
+
+  void DoFinalPass(cmMakefile* mf)
+  {
+    SignalHandlerGuard guard(this->Name);
+    this->FinalPass(this, mf);
+  }
+};
 
 // a class for loadabple commands
 class cmLoadedCommand : public cmCommand
 {
 public:
-  cmLoadedCommand()
+  cmLoadedCommand() = default;
+  explicit cmLoadedCommand(CM_INIT_FUNCTION init)
+    : Impl(std::make_shared<LoadedCommandImpl>(init))
   {
-    memset(&this->info, 0, sizeof(this->info));
-    this->info.CAPI = &cmStaticCAPI;
   }
 
-  //! clean up any memory allocated by the plugin
-  ~cmLoadedCommand() override;
-
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override
+  std::unique_ptr<cmCommand> Clone() override
   {
-    cmLoadedCommand* newC = new cmLoadedCommand;
+    auto newC = cm::make_unique<cmLoadedCommand>();
     // we must copy when we clone
-    memcpy(&newC->info, &this->info, sizeof(info));
-    return newC;
+    newC->Impl = this->Impl;
+    return std::unique_ptr<cmCommand>(std::move(newC));
   }
 
   /**
@@ -54,66 +126,20 @@
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus&) override;
 
-  /**
-   * This is called at the end after all the information
-   * specified by the command is accumulated. Most commands do
-   * not implement this method.  At this point, reading and
-   * writing to the cache can be done.
-   */
-  void FinalPass() override;
-  bool HasFinalPass() const override
-  {
-    return this->info.FinalPass != nullptr;
-  }
-
-  static const char* LastName;
-  static void TrapsForSignals(int sig)
-  {
-    fprintf(stderr, "CMake loaded command %s crashed with signal: %d.\n",
-            cmLoadedCommand::LastName, sig);
-  }
-  static void InstallSignalHandlers(const char* name, int remove = 0)
-  {
-    cmLoadedCommand::LastName = name;
-    if (!name) {
-      cmLoadedCommand::LastName = "????";
-    }
-
-    if (!remove) {
-      signal(SIGSEGV, TrapsForSignalsCFunction);
-#ifdef SIGBUS
-      signal(SIGBUS, TrapsForSignalsCFunction);
-#endif
-      signal(SIGILL, TrapsForSignalsCFunction);
-    } else {
-      signal(SIGSEGV, nullptr);
-#ifdef SIGBUS
-      signal(SIGBUS, nullptr);
-#endif
-      signal(SIGILL, nullptr);
-    }
-  }
-
-  cmLoadedCommandInfo info;
+private:
+  std::shared_ptr<LoadedCommandImpl> Impl;
 };
 
-extern "C" void TrapsForSignalsCFunction(int sig)
-{
-  cmLoadedCommand::TrapsForSignals(sig);
-}
-
-const char* cmLoadedCommand::LastName = nullptr;
-
 bool cmLoadedCommand::InitialPass(std::vector<std::string> const& args,
                                   cmExecutionStatus&)
 {
-  if (!info.InitialPass) {
+  if (!this->Impl->InitialPass) {
     return true;
   }
 
   // clear the error string
-  if (this->info.Error) {
-    free(this->info.Error);
+  if (this->Impl->Error) {
+    free(this->Impl->Error);
   }
 
   // create argc and argv and then invoke the command
@@ -126,42 +152,26 @@
   for (i = 0; i < argc; ++i) {
     argv[i] = strdup(args[i].c_str());
   }
-  cmLoadedCommand::InstallSignalHandlers(info.Name);
-  int result = info.InitialPass(&info, this->Makefile, argc, argv);
-  cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
+  int result = this->Impl->DoInitialPass(this->Makefile, argc, argv);
   cmFreeArguments(argc, argv);
 
   if (result) {
+    if (this->Impl->FinalPass) {
+      auto impl = this->Impl;
+      this->Makefile->AddFinalAction(
+        [impl](cmMakefile& makefile) { impl->DoFinalPass(&makefile); });
+    }
     return true;
   }
 
   /* Initial Pass must have failed so set the error string */
-  if (this->info.Error) {
-    this->SetError(this->info.Error);
+  if (this->Impl->Error) {
+    this->SetError(this->Impl->Error);
   }
   return false;
 }
 
-void cmLoadedCommand::FinalPass()
-{
-  if (this->info.FinalPass) {
-    cmLoadedCommand::InstallSignalHandlers(info.Name);
-    this->info.FinalPass(&this->info, this->Makefile);
-    cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
-  }
-}
-
-cmLoadedCommand::~cmLoadedCommand()
-{
-  if (this->info.Destructor) {
-    cmLoadedCommand::InstallSignalHandlers(info.Name);
-    this->info.Destructor(&this->info);
-    cmLoadedCommand::InstallSignalHandlers(info.Name, 1);
-  }
-  if (this->info.Error) {
-    free(this->info.Error);
-  }
-}
+} // namespace
 
 // cmLoadCommandCommand
 bool cmLoadCommandCommand::InitialPass(std::vector<std::string> const& args,
@@ -220,7 +230,7 @@
   }
 
   // Report what file was loaded for this command.
-  this->Makefile->AddDefinition(reportVar, fullPath.c_str());
+  this->Makefile->AddDefinition(reportVar, fullPath);
 
   // find the init function
   std::string initFuncName = args[0] + "Init";
@@ -236,10 +246,9 @@
   // if the symbol is found call it to set the name on the
   // function blocker
   if (initFunction) {
-    // create a function blocker and set it up
-    cmLoadedCommand* f = new cmLoadedCommand();
-    (*initFunction)(&f->info);
-    this->Makefile->GetState()->AddScriptedCommand(args[0], f);
+    this->Makefile->GetState()->AddScriptedCommand(
+      args[0],
+      cmLegacyCommandWrapper(cm::make_unique<cmLoadedCommand>(initFunction)));
     return true;
   }
   this->SetError("Attempt to load command failed. "
diff --git a/Source/cmLoadCommandCommand.h b/Source/cmLoadCommandCommand.h
index 021e6c7..d81cefb 100644
--- a/Source/cmLoadCommandCommand.h
+++ b/Source/cmLoadCommandCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,7 +17,10 @@
 class cmLoadCommandCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmLoadCommandCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmLoadCommandCommand>();
+  }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
 };
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 0f730c9..242ffe3 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1134,11 +1134,13 @@
                                              std::string const& linkLanguage,
                                              cmGeneratorTarget* target)
 {
-  this->AppendFlags(
-    flags, this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS"));
-  if (!config.empty()) {
-    std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + config;
-    this->AppendFlags(flags, this->Makefile->GetSafeDefinition(name));
+  if (linkLanguage != "Swift") {
+    this->AppendFlags(
+      flags, this->Makefile->GetSafeDefinition("CMAKE_STATIC_LINKER_FLAGS"));
+    if (!config.empty()) {
+      std::string name = "CMAKE_STATIC_LINKER_FLAGS_" + config;
+      this->AppendFlags(flags, this->Makefile->GetSafeDefinition(name));
+    }
   }
   this->AppendFlags(flags, target->GetProperty("STATIC_LIBRARY_FLAGS"));
   if (!config.empty()) {
@@ -1515,8 +1517,10 @@
         }
         CM_FALLTHROUGH;
       case cmPolicies::OLD:
-        // OLD behavior is to always add the flags
-        add_shlib_flags = true;
+        // OLD behavior is to always add the flags, except on AIX where
+        // we compute symbol exports if ENABLE_EXPORTS is on.
+        add_shlib_flags =
+          !(tgt.Target->IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS"));
         break;
       case cmPolicies::REQUIRED_IF_USED:
       case cmPolicies::REQUIRED_ALWAYS:
@@ -1525,8 +1529,10 @@
           cmPolicies::GetRequiredPolicyError(cmPolicies::CMP0065));
         CM_FALLTHROUGH;
       case cmPolicies::NEW:
-        // NEW behavior is to only add the flags if ENABLE_EXPORTS is on
-        add_shlib_flags = tgt.GetPropertyAsBool("ENABLE_EXPORTS");
+        // NEW behavior is to only add the flags if ENABLE_EXPORTS is on,
+        // except on AIX where we compute symbol exports.
+        add_shlib_flags =
+          !tgt.Target->IsAIX() && tgt.GetPropertyAsBool("ENABLE_EXPORTS");
         break;
     }
 
@@ -2967,7 +2973,7 @@
   // back to the directory-level values set by the user.
   cmMakefile* mf = this->Makefile;
   cmMakefile::ScopePushPop varScope(mf);
-  mf->AddDefinition("MACOSX_BUNDLE_EXECUTABLE_NAME", targetName.c_str());
+  mf->AddDefinition("MACOSX_BUNDLE_EXECUTABLE_NAME", targetName);
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_INFO_STRING");
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_ICON_FILE");
   cmLGInfoProp(mf, target, "MACOSX_BUNDLE_GUI_IDENTIFIER");
@@ -3006,7 +3012,7 @@
   // back to the directory-level values set by the user.
   cmMakefile* mf = this->Makefile;
   cmMakefile::ScopePushPop varScope(mf);
-  mf->AddDefinition("MACOSX_FRAMEWORK_NAME", targetName.c_str());
+  mf->AddDefinition("MACOSX_FRAMEWORK_NAME", targetName);
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_ICON_FILE");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_IDENTIFIER");
   cmLGInfoProp(mf, target, "MACOSX_FRAMEWORK_SHORT_VERSION_STRING");
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index 1b4f428..1ec1fd9 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -5,11 +5,12 @@
 #include "cmsys/FStream.hxx"
 #include "cmsys/Terminal.h"
 #include <algorithm>
-#include <memory>
 #include <sstream>
 #include <stdio.h>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmCustomCommand.h" // IWYU pragma: keep
 #include "cmCustomCommandGenerator.h"
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index 7ba3471..8154f3e 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -703,8 +703,7 @@
   }
   Options targetOptions(this, t, table, gg->ExtraFlagTable);
   targetOptions.FixExceptionHandlingDefault();
-  std::string asmLocation = configName + "/";
-  targetOptions.AddFlag("AssemblerListingLocation", asmLocation);
+  targetOptions.AddFlag("AssemblerListingLocation", "$(IntDir)\\");
   targetOptions.Parse(flags);
   targetOptions.Parse(defineFlags);
   targetOptions.ParseFinish();
diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx
index ac6dce9..bec3ad8 100644
--- a/Source/cmMachO.cxx
+++ b/Source/cmMachO.cxx
@@ -4,10 +4,13 @@
 
 #include "cmAlgorithms.h"
 #include "cmsys/FStream.hxx"
+
 #include <cstddef>
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 // Include the Mach-O format information system header.
 #include <mach-o/fat.h>
 #include <mach-o/loader.h>
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index e9c6aea..22748b4 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -6,6 +6,8 @@
 #include <stdio.h>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmExecutionStatus.h"
 #include "cmMakefile.h"
@@ -15,35 +17,15 @@
 #include "cmSystemTools.h"
 
 // define the class for macro commands
-class cmMacroHelperCommand : public cmCommand
+class cmMacroHelperCommand
 {
 public:
   /**
-   * This is a virtual constructor for the command.
-   */
-  cmCommand* Clone() override
-  {
-    cmMacroHelperCommand* newC = new cmMacroHelperCommand;
-    // we must copy when we clone
-    newC->Args = this->Args;
-    newC->Functions = this->Functions;
-    newC->FilePath = this->FilePath;
-    newC->Policies = this->Policies;
-    return newC;
-  }
-
-  /**
    * This is called when the command is first encountered in
    * the CMakeLists.txt file.
    */
-  bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
-                         cmExecutionStatus&) override;
-
-  bool InitialPass(std::vector<std::string> const&,
-                   cmExecutionStatus&) override
-  {
-    return false;
-  }
+  bool operator()(std::vector<cmListFileArgument> const& args,
+                  cmExecutionStatus& inStatus) const;
 
   std::vector<std::string> Args;
   std::vector<cmListFileFunction> Functions;
@@ -51,12 +33,15 @@
   std::string FilePath;
 };
 
-bool cmMacroHelperCommand::InvokeInitialPass(
-  const std::vector<cmListFileArgument>& args, cmExecutionStatus& inStatus)
+bool cmMacroHelperCommand::operator()(
+  std::vector<cmListFileArgument> const& args,
+  cmExecutionStatus& inStatus) const
 {
+  cmMakefile& makefile = inStatus.GetMakefile();
+
   // Expand the argument list to the macro.
   std::vector<std::string> expandedArgs;
-  this->Makefile->ExpandArguments(args, expandedArgs);
+  makefile.ExpandArguments(args, expandedArgs);
 
   // make sure the number of arguments passed is at least the number
   // required by the signature
@@ -64,11 +49,11 @@
     std::string errorMsg =
       "Macro invoked with incorrect arguments for macro named: ";
     errorMsg += this->Args[0];
-    this->SetError(errorMsg);
+    inStatus.SetError(errorMsg);
     return false;
   }
 
-  cmMakefile::MacroPushPop macroScope(this->Makefile, this->FilePath,
+  cmMakefile::MacroPushPop macroScope(&makefile, this->FilePath,
                                       this->Policies);
 
   // set the value of argc
@@ -130,9 +115,8 @@
       arg.Line = k.Line;
       newLFF.Arguments.push_back(std::move(arg));
     }
-    cmExecutionStatus status;
-    if (!this->Makefile->ExecuteCommand(newLFF, status) ||
-        status.GetNestedError()) {
+    cmExecutionStatus status(makefile);
+    if (!makefile.ExecuteCommand(newLFF, status) || status.GetNestedError()) {
       // The error message should have already included the call stack
       // so we do not need to report an error here.
       macroScope.Quiet();
@@ -164,12 +148,12 @@
     if (!this->Depth) {
       mf.AppendProperty("MACROS", this->Args[0].c_str());
       // create a new command and add it to cmake
-      cmMacroHelperCommand* f = new cmMacroHelperCommand();
-      f->Args = this->Args;
-      f->Functions = this->Functions;
-      f->FilePath = this->GetStartingContext().FilePath;
-      mf.RecordPolicies(f->Policies);
-      mf.GetState()->AddScriptedCommand(this->Args[0], f);
+      cmMacroHelperCommand f;
+      f.Args = this->Args;
+      f.Functions = this->Functions;
+      f.FilePath = this->GetStartingContext().FilePath;
+      mf.RecordPolicies(f.Policies);
+      mf.GetState()->AddScriptedCommand(this->Args[0], std::move(f));
       // remove the function blocker now that the macro is defined
       mf.RemoveFunctionBlocker(this, lff);
       return true;
@@ -211,8 +195,10 @@
   }
 
   // create a function blocker
-  cmMacroFunctionBlocker* f = new cmMacroFunctionBlocker();
-  cmAppend(f->Args, args);
-  this->Makefile->AddFunctionBlocker(f);
+  {
+    auto fb = cm::make_unique<cmMacroFunctionBlocker>();
+    cmAppend(fb->Args, args);
+    this->Makefile->AddFunctionBlocker(std::move(fb));
+  }
   return true;
 }
diff --git a/Source/cmMacroCommand.h b/Source/cmMacroCommand.h
index b54ed66..3ebd959 100644
--- a/Source/cmMacroCommand.h
+++ b/Source/cmMacroCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 #include "cmFunctionBlocker.h"
 #include "cmListFileCache.h"
@@ -34,7 +36,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmMacroCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmMacroCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmMakeDirectoryCommand.h b/Source/cmMakeDirectoryCommand.h
index d2637f3..b1fb49b 100644
--- a/Source/cmMakeDirectoryCommand.h
+++ b/Source/cmMakeDirectoryCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -27,7 +29,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmMakeDirectoryCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmMakeDirectoryCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 5f22a07..0fb3237 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -16,7 +16,6 @@
 #include <utility>
 
 #include "cmAlgorithms.h"
-#include "cmCommand.h"
 #include "cmCommandArgumentParserHelper.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandLines.h"
@@ -118,8 +117,6 @@
   cmDeleteAll(this->SourceFiles);
   cmDeleteAll(this->Tests);
   cmDeleteAll(this->ImportedTargetsOwned);
-  cmDeleteAll(this->FinalPassCommands);
-  cmDeleteAll(this->FunctionBlockers);
   cmDeleteAll(this->EvaluationFiles);
 }
 
@@ -390,12 +387,8 @@
   }
 
   // Lookup the command prototype.
-  if (cmCommand* proto =
+  if (cmState::Command command =
         this->GetState()->GetCommandByExactName(lff.Name.Lower)) {
-    // Clone the prototype.
-    std::unique_ptr<cmCommand> pcmd(proto->Clone());
-    pcmd->SetMakefile(this);
-
     // Decide whether to invoke the command.
     if (!cmSystemTools::GetFatalErrorOccured()) {
       // if trace is enabled, print out invoke information
@@ -403,22 +396,19 @@
         this->PrintCommandTrace(lff);
       }
       // Try invoking the command.
-      bool invokeSucceeded = pcmd->InvokeInitialPass(lff.Arguments, status);
+      bool invokeSucceeded = command(lff.Arguments, status);
       bool hadNestedError = status.GetNestedError();
       if (!invokeSucceeded || hadNestedError) {
         if (!hadNestedError) {
           // The command invocation requested that we report an error.
           std::string const error =
-            std::string(lff.Name.Original) + " " + pcmd->GetError();
+            std::string(lff.Name.Original) + " " + status.GetError();
           this->IssueMessage(MessageType::FATAL_ERROR, error);
         }
         result = false;
         if (this->GetCMakeInstance()->GetWorkingMode() != cmake::NORMAL_MODE) {
           cmSystemTools::SetFatalErrorOccured();
         }
-      } else if (pcmd->HasFinalPass()) {
-        // use the command
-        this->FinalPassCommands.push_back(pcmd.release());
       }
     }
   } else {
@@ -567,8 +557,9 @@
 bool cmMakefile::ReadDependentFile(const std::string& filename,
                                    bool noPolicyScope)
 {
-  this->AddDefinition("CMAKE_PARENT_LIST_FILE",
-                      this->GetDefinition("CMAKE_CURRENT_LIST_FILE"));
+  if (const char* def = this->GetDefinition("CMAKE_CURRENT_LIST_FILE")) {
+    this->AddDefinition("CMAKE_PARENT_LIST_FILE", def);
+  }
   std::string filenametoread = cmSystemTools::CollapseFullPath(
     filename, this->GetCurrentSourceDirectory());
 
@@ -651,9 +642,9 @@
     this->GetSafeDefinition("CMAKE_PARENT_LIST_FILE");
   std::string currentFile = this->GetSafeDefinition("CMAKE_CURRENT_LIST_FILE");
 
-  this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread.c_str());
+  this->AddDefinition("CMAKE_CURRENT_LIST_FILE", filenametoread);
   this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
-                      cmSystemTools::GetFilenamePath(filenametoread).c_str());
+                      cmSystemTools::GetFilenamePath(filenametoread));
 
   this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
   this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
@@ -662,7 +653,7 @@
   // Run the parsed commands.
   const size_t numberFunctions = listFile.Functions.size();
   for (size_t i = 0; i < numberFunctions; ++i) {
-    cmExecutionStatus status;
+    cmExecutionStatus status(*this);
     this->ExecuteCommand(listFile.Functions[i], status);
     if (cmSystemTools::GetFatalErrorOccured()) {
       break;
@@ -674,10 +665,10 @@
   }
   this->CheckForUnusedVariables();
 
-  this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile.c_str());
-  this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile.c_str());
+  this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentParentFile);
+  this->AddDefinition("CMAKE_CURRENT_LIST_FILE", currentFile);
   this->AddDefinition("CMAKE_CURRENT_LIST_DIR",
-                      cmSystemTools::GetFilenamePath(currentFile).c_str());
+                      cmSystemTools::GetFilenamePath(currentFile));
   this->MarkVariableAsUsed("CMAKE_PARENT_LIST_FILE");
   this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_FILE");
   this->MarkVariableAsUsed("CMAKE_CURRENT_LIST_DIR");
@@ -769,6 +760,11 @@
 };
 }
 
+void cmMakefile::AddFinalAction(FinalAction action)
+{
+  this->FinalActions.push_back(std::move(action));
+}
+
 void cmMakefile::FinalPass()
 {
   // do all the variable expansions here
@@ -776,8 +772,8 @@
 
   // give all the commands a chance to do something
   // after the file has been parsed before generation
-  for (cmCommand* fpCommand : this->FinalPassCommands) {
-    fpCommand->FinalPass();
+  for (FinalAction& action : this->FinalActions) {
+    action(*this);
   }
 
   // go through all configured files and see which ones still exist.
@@ -1540,7 +1536,7 @@
   cmSystemTools::MakeDirectory(filesDir);
 
   assert(cmSystemTools::FileExists(currentStart, true));
-  this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart.c_str());
+  this->AddDefinition("CMAKE_PARENT_LIST_FILE", currentStart);
 
   cmListFile listFile;
   if (!listFile.ParseFile(currentStart.c_str(), this->GetMessenger(),
@@ -1788,12 +1784,8 @@
   }
 }
 
-void cmMakefile::AddDefinition(const std::string& name, const char* value)
+void cmMakefile::AddDefinition(const std::string& name, cm::string_view value)
 {
-  if (!value) {
-    return;
-  }
-
   if (this->VariableInitialized(name)) {
     this->LogUnused("changing definition", name);
   }
@@ -1803,11 +1795,16 @@
   cmVariableWatch* vv = this->GetVariableWatch();
   if (vv) {
     vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
-                         value, this);
+                         value.data(), this);
   }
 #endif
 }
 
+void cmMakefile::AddDefinitionBool(const std::string& name, bool value)
+{
+  this->AddDefinition(name, value ? "ON" : "OFF");
+}
+
 void cmMakefile::AddCacheDefinition(const std::string& name, const char* value,
                                     const char* doc,
                                     cmStateEnums::CacheEntryType type,
@@ -1853,23 +1850,6 @@
   this->StateSnapshot.RemoveDefinition(name);
 }
 
-void cmMakefile::AddDefinition(const std::string& name, bool value)
-{
-  if (this->VariableInitialized(name)) {
-    this->LogUnused("changing definition", name);
-  }
-
-  this->StateSnapshot.SetDefinition(name, value ? "ON" : "OFF");
-
-#ifdef CMAKE_BUILD_WITH_CMAKE
-  cmVariableWatch* vv = this->GetVariableWatch();
-  if (vv) {
-    vv->VariableAccessed(name, cmVariableWatch::VARIABLE_MODIFIED_ACCESS,
-                         value ? "ON" : "OFF", this);
-  }
-#endif
-}
-
 void cmMakefile::CheckForUnusedVariables() const
 {
   if (!this->WarnUnused) {
@@ -3077,13 +3057,13 @@
                                    cmExecutionStatus& status)
 {
   // if there are no blockers get out of here
-  if (this->FunctionBlockers.begin() == this->FunctionBlockers.end()) {
+  if (this->FunctionBlockers.empty()) {
     return false;
   }
 
   // loop over all function blockers to see if any block this command
   // evaluate in reverse, this is critical for balanced IF statements etc
-  for (cmFunctionBlocker* pos : cmReverseRange(this->FunctionBlockers)) {
+  for (auto const& pos : cmReverseRange(this->FunctionBlockers)) {
     if (pos->IsFunctionBlocked(lff, *this, status)) {
       return true;
     }
@@ -3103,7 +3083,8 @@
   FunctionBlockersType::size_type barrier =
     this->FunctionBlockerBarriers.back();
   while (this->FunctionBlockers.size() > barrier) {
-    std::unique_ptr<cmFunctionBlocker> fb(this->FunctionBlockers.back());
+    std::unique_ptr<cmFunctionBlocker> fb(
+      std::move(this->FunctionBlockers.back()));
     this->FunctionBlockers.pop_back();
     if (reportError) {
       // Report the context in which the unclosed block was opened.
@@ -3228,14 +3209,14 @@
   return !cmSystemTools::GetFatalErrorOccured();
 }
 
-void cmMakefile::AddFunctionBlocker(cmFunctionBlocker* fb)
+void cmMakefile::AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb)
 {
   if (!this->ExecutionStatusStack.empty()) {
     // Record the context in which the blocker is created.
     fb->SetStartingContext(this->GetExecutionContext());
   }
 
-  this->FunctionBlockers.push_back(fb);
+  this->FunctionBlockers.push_back(std::move(fb));
 }
 
 std::unique_ptr<cmFunctionBlocker> cmMakefile::RemoveFunctionBlocker(
@@ -3251,9 +3232,8 @@
   // Search for the function blocker whose scope this command ends.
   for (FunctionBlockersType::size_type i = this->FunctionBlockers.size();
        i > barrier; --i) {
-    std::vector<cmFunctionBlocker*>::iterator pos =
-      this->FunctionBlockers.begin() + (i - 1);
-    if (*pos == fb) {
+    auto pos = this->FunctionBlockers.begin() + (i - 1);
+    if (pos->get() == fb) {
       // Warn if the arguments do not match, but always remove.
       if (!(*pos)->ShouldRemove(lff, *this)) {
         cmListFileContext const& lfc = fb->GetStartingContext();
@@ -3269,9 +3249,9 @@
         /* clang-format on */
         this->IssueMessage(MessageType::AUTHOR_WARNING, e.str());
       }
-      cmFunctionBlocker* b = *pos;
+      std::unique_ptr<cmFunctionBlocker> b = std::move(*pos);
       this->FunctionBlockers.erase(pos);
-      return std::unique_ptr<cmFunctionBlocker>(b);
+      return b;
     }
   }
 
@@ -3290,20 +3270,20 @@
 
 void cmMakefile::SetScriptModeFile(std::string const& scriptfile)
 {
-  this->AddDefinition("CMAKE_SCRIPT_MODE_FILE", scriptfile.c_str());
+  this->AddDefinition("CMAKE_SCRIPT_MODE_FILE", scriptfile);
 }
 
 void cmMakefile::SetArgcArgv(const std::vector<std::string>& args)
 {
   std::ostringstream strStream;
   strStream << args.size();
-  this->AddDefinition("CMAKE_ARGC", strStream.str().c_str());
+  this->AddDefinition("CMAKE_ARGC", strStream.str());
   // this->MarkVariableAsUsed("CMAKE_ARGC");
 
   for (unsigned int t = 0; t < args.size(); ++t) {
     std::ostringstream tmpStream;
     tmpStream << "CMAKE_ARGV" << t;
-    this->AddDefinition(tmpStream.str(), args[t].c_str());
+    this->AddDefinition(tmpStream.str(), args[t]);
     // this->MarkVariableAsUsed(tmpStream.str().c_str());
   }
 }
@@ -3384,8 +3364,9 @@
 void cmMakefile::EnableLanguage(std::vector<std::string> const& lang,
                                 bool optional)
 {
-  this->AddDefinition("CMAKE_CFG_INTDIR",
-                      this->GetGlobalGenerator()->GetCMakeCFGIntDir());
+  if (const char* def = this->GetGlobalGenerator()->GetCMakeCFGIntDir()) {
+    this->AddDefinition("CMAKE_CFG_INTDIR", def);
+  }
   // If RC is explicitly listed we need to do it after other languages.
   // On some platforms we enable RC implicitly while enabling others.
   // Do not let that look like recursive enable_language(RC).
@@ -4237,7 +4218,7 @@
     std::string const& m = re.match(i);
     if (!m.empty()) {
       std::string const& var = matchVariables[i];
-      this->AddDefinition(var, m.c_str());
+      this->AddDefinition(var, m);
       this->MarkVariableAsUsed(var);
       highest = static_cast<char>('0' + i);
     }
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index d0b70d9..18b81d4 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -7,6 +7,7 @@
 
 #include "cmsys/RegularExpression.hxx"
 #include <deque>
+#include <functional>
 #include <map>
 #include <memory>
 #include <set>
@@ -16,7 +17,10 @@
 #include <unordered_map>
 #include <vector>
 
+#include "cm_string_view.hxx"
+
 #include "cmAlgorithms.h"
+#include "cmFunctionBlocker.h"
 #include "cmListFileCache.h"
 #include "cmMessageType.h"
 #include "cmNewLineStyle.h"
@@ -30,13 +34,11 @@
 #  include "cmSourceGroup.h"
 #endif
 
-class cmCommand;
 class cmCompiledGeneratorExpression;
 class cmCustomCommandLines;
 class cmExecutionStatus;
 class cmExpandedCommandArgument;
 class cmExportBuildFileGenerator;
-class cmFunctionBlocker;
 class cmGeneratorExpressionEvaluationFile;
 class cmGlobalGenerator;
 class cmInstallGenerator;
@@ -95,7 +97,7 @@
   /**
    * Add a function blocker to this makefile
    */
-  void AddFunctionBlocker(cmFunctionBlocker* fb);
+  void AddFunctionBlocker(std::unique_ptr<cmFunctionBlocker> fb);
 
   /// @return whether we are processing the top CMakeLists.txt file.
   bool IsRootMakefile() const;
@@ -125,6 +127,13 @@
   bool EnforceUniqueName(std::string const& name, std::string& msg,
                          bool isCustom = false) const;
 
+  using FinalAction = std::function<void(cmMakefile&)>;
+
+  /**
+   * Register an action that is executed during FinalPass
+   */
+  void AddFinalAction(FinalAction action);
+
   /**
    * Perform FinalPass, Library dependency analysis etc before output of the
    * makefile.
@@ -132,7 +141,7 @@
   void ConfigureFinalPass();
 
   /**
-   * run the final pass on all commands.
+   * run all FinalActions.
    */
   void FinalPass();
 
@@ -256,18 +265,17 @@
    * Add a variable definition to the build. This variable
    * can be used in CMake to refer to lists, directories, etc.
    */
-  void AddDefinition(const std::string& name, const char* value);
+  void AddDefinition(const std::string& name, cm::string_view value);
+  /**
+   * Add bool variable definition to the build.
+   */
+  void AddDefinitionBool(const std::string& name, bool);
   //! Add a definition to this makefile and the global cmake cache.
   void AddCacheDefinition(const std::string& name, const char* value,
                           const char* doc, cmStateEnums::CacheEntryType type,
                           bool force = false);
 
   /**
-   * Add bool variable definition to the build.
-   */
-  void AddDefinition(const std::string& name, bool);
-
-  /**
    * Remove a variable definition from the build.  This is not valid
    * for cache entries, and will only affect the current makefile.
    */
@@ -937,7 +945,7 @@
   size_t ObjectLibrariesSourceGroupIndex;
 #endif
 
-  std::vector<cmCommand*> FinalPassCommands;
+  std::vector<FinalAction> FinalActions;
   cmGlobalGenerator* GlobalGenerator;
   bool IsFunctionBlocked(const cmListFileFunction& lff,
                          cmExecutionStatus& status);
@@ -955,7 +963,7 @@
   bool EnforceUniqueDir(const std::string& srcPath,
                         const std::string& binPath) const;
 
-  typedef std::vector<cmFunctionBlocker*> FunctionBlockersType;
+  typedef std::vector<std::unique_ptr<cmFunctionBlocker>> FunctionBlockersType;
   FunctionBlockersType FunctionBlockers;
   std::vector<FunctionBlockersType::size_type> FunctionBlockerBarriers;
   void PushFunctionBlockerBarrier();
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 2001c1f..a7f2a97 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -2,13 +2,14 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmMakefileExecutableTargetGenerator.h"
 
-#include <memory>
 #include <set>
 #include <sstream>
 #include <string>
 #include <utility>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
@@ -482,9 +483,8 @@
 
   // Construct the main link rule.
   std::vector<std::string> real_link_commands;
-  std::string linkRuleVar = "CMAKE_";
-  linkRuleVar += linkLanguage;
-  linkRuleVar += "_LINK_EXECUTABLE";
+  std::string linkRuleVar = this->GeneratorTarget->GetCreateRuleVariable(
+    linkLanguage, this->ConfigName);
   std::string linkRule = this->GetLinkRule(linkRuleVar);
   std::vector<std::string> commands1;
   cmSystemTools::ExpandListArgument(linkRule, real_link_commands);
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index e5aed01..bdde4b8 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -2,13 +2,14 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmMakefileLibraryTargetGenerator.h"
 
-#include <memory>
 #include <set>
 #include <sstream>
 #include <stddef.h>
 #include <utility>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
diff --git a/Source/cmMakefileUtilityTargetGenerator.cxx b/Source/cmMakefileUtilityTargetGenerator.cxx
index 70d9fca..8ed6be5 100644
--- a/Source/cmMakefileUtilityTargetGenerator.cxx
+++ b/Source/cmMakefileUtilityTargetGenerator.cxx
@@ -2,13 +2,13 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmMakefileUtilityTargetGenerator.h"
 
-#include <memory>
 #include <ostream>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "cmAlgorithms.h"
+#include "cm_memory.hxx"
+
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalUnixMakefileGenerator3.h"
diff --git a/Source/cmMarkAsAdvancedCommand.h b/Source/cmMarkAsAdvancedCommand.h
index 5dd198f..e367c46 100644
--- a/Source/cmMarkAsAdvancedCommand.h
+++ b/Source/cmMarkAsAdvancedCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmMarkAsAdvancedCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmMarkAsAdvancedCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmMathCommand.h b/Source/cmMathCommand.h
index 0c6c76b..23633d3 100644
--- a/Source/cmMathCommand.h
+++ b/Source/cmMathCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -19,7 +21,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmMathCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmMathCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index 5320ec5..58f3b2f 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -25,7 +25,6 @@
   auto i = args.cbegin();
 
   auto type = MessageType::MESSAGE;
-  auto status = false;
   auto fatal = false;
   auto level = cmake::LogLevel::LOG_UNDEFINED;
   if (*i == "SEND_ERROR") {
@@ -55,19 +54,15 @@
     }
     ++i;
   } else if (*i == "STATUS") {
-    status = true;
     level = cmake::LogLevel::LOG_STATUS;
     ++i;
   } else if (*i == "VERBOSE") {
-    status = true;
     level = cmake::LogLevel::LOG_VERBOSE;
     ++i;
   } else if (*i == "DEBUG") {
-    status = true;
     level = cmake::LogLevel::LOG_DEBUG;
     ++i;
   } else if (*i == "TRACE") {
-    status = true;
     level = cmake::LogLevel::LOG_TRACE;
     ++i;
   } else if (*i == "DEPRECATION") {
@@ -105,17 +100,46 @@
 
   auto message = cmJoin(cmMakeRange(i, args.cend()), "");
 
-  if (type != MessageType::MESSAGE) {
-    // we've overridden the message type, above, so display it directly
-    cmMessenger* m = this->Makefile->GetMessenger();
-    m->DisplayMessage(type, message, this->Makefile->GetBacktrace());
-  } else {
-    if (status) {
-      this->Makefile->DisplayStatus(message, -1);
-    } else {
-      cmSystemTools::Message(message);
-    }
+  if (cmake::LogLevel::LOG_NOTICE <= level) {
+    // Check if any indentation has requested:
+    // `CMAKE_MESSAGE_INDENT` is a list of "padding" pieces
+    // to be joined and prepended to the message lines.
+    auto indent =
+      cmJoin(cmSystemTools::ExpandedListArgument(
+               this->Makefile->GetSafeDefinition("CMAKE_MESSAGE_INDENT")),
+             "");
+    // Make every line of the `message` indented
+    // NOTE Can't reuse `cmDocumentationFormatter::PrintPreformatted`
+    // here cuz it appends `\n` to the EOM ;-(
+    cmSystemTools::ReplaceString(message, "\n", "\n" + indent);
+    message = indent + message;
   }
+
+  switch (level) {
+    case cmake::LogLevel::LOG_ERROR:
+    case cmake::LogLevel::LOG_WARNING:
+      // we've overridden the message type, above, so display it directly
+      this->Makefile->GetMessenger()->DisplayMessage(
+        type, message, this->Makefile->GetBacktrace());
+      break;
+
+    case cmake::LogLevel::LOG_NOTICE:
+      cmSystemTools::Message(message);
+      break;
+
+    case cmake::LogLevel::LOG_STATUS:
+    case cmake::LogLevel::LOG_VERBOSE:
+    case cmake::LogLevel::LOG_DEBUG:
+    case cmake::LogLevel::LOG_TRACE:
+      this->Makefile->DisplayStatus(message, -1);
+      break;
+
+    default:
+      assert("Unexpected log level! Review the `cmMessageCommand.cxx`." &&
+             false);
+      break;
+  }
+
   if (fatal) {
     cmSystemTools::SetFatalErrorOccured();
   }
diff --git a/Source/cmMessageCommand.h b/Source/cmMessageCommand.h
index 819ebda..ef89d59 100644
--- a/Source/cmMessageCommand.h
+++ b/Source/cmMessageCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -22,7 +24,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmMessageCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmMessageCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmMessenger.cxx b/Source/cmMessenger.cxx
index 1d790e2..0d2b21f 100644
--- a/Source/cmMessenger.cxx
+++ b/Source/cmMessenger.cxx
@@ -100,8 +100,7 @@
            "it.";
   } else if (t == MessageType::AUTHOR_ERROR) {
     msg << "This error is for project developers. Use -Wno-error=dev to "
-           "suppress "
-           "it.";
+           "suppress it.";
   }
 
   // Add a terminating blank line.
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index d1af9e6..88040f8 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -6,11 +6,12 @@
 #include <assert.h>
 #include <iterator>
 #include <map>
-#include <memory>
 #include <set>
 #include <sstream>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmCustomCommand.h" // IWYU pragma: keep
 #include "cmCustomCommandGenerator.h"
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 57e500e..08c92ff 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -8,10 +8,11 @@
 #include <assert.h>
 #include <iterator>
 #include <map>
-#include <memory>
 #include <ostream>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmComputeLinkInformation.h"
 #include "cmCustomCommandGenerator.h"
@@ -909,8 +910,8 @@
   this->GetBuildFileStream() << "\n";
 
   if (!this->SwiftOutputMap.empty()) {
-    std::string const mapFilePath = this->ConvertToNinjaPath(
-      this->GeneratorTarget->GetSupportDirectory() + "/output-file-map.json");
+    std::string const mapFilePath =
+      this->GeneratorTarget->GetSupportDirectory() + "/output-file-map.json";
     std::string const targetSwiftDepsPath = [this]() -> std::string {
       cmGeneratorTarget const* target = this->GeneratorTarget;
       if (const char* name = target->GetProperty("Swift_DEPENDENCIES_FILE")) {
diff --git a/Source/cmOptionCommand.h b/Source/cmOptionCommand.h
index 34e0e6f..eddab03 100644
--- a/Source/cmOptionCommand.h
+++ b/Source/cmOptionCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmOptionCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmOptionCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmOutputRequiredFilesCommand.h b/Source/cmOutputRequiredFilesCommand.h
index 09e622b..faffabd 100644
--- a/Source/cmOutputRequiredFilesCommand.h
+++ b/Source/cmOutputRequiredFilesCommand.h
@@ -10,6 +10,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmDependInformation;
@@ -18,7 +20,10 @@
 class cmOutputRequiredFilesCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmOutputRequiredFilesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmOutputRequiredFilesCommand>();
+  }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
 
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
index 5213432..0f8aef7 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -75,7 +75,7 @@
 
   for (auto const& iter : singleValArgs) {
     if (!iter.second.empty()) {
-      makefile.AddDefinition(prefix + iter.first, iter.second.c_str());
+      makefile.AddDefinition(prefix + iter.first, iter.second);
     } else {
       makefile.RemoveDefinition(prefix + iter.first);
     }
@@ -84,7 +84,7 @@
   for (auto const& iter : multiValArgs) {
     if (!iter.second.empty()) {
       makefile.AddDefinition(prefix + iter.first,
-                             JoinList(iter.second, parseFromArgV).c_str());
+                             JoinList(iter.second, parseFromArgV));
     } else {
       makefile.RemoveDefinition(prefix + iter.first);
     }
@@ -92,15 +92,14 @@
 
   if (!unparsed.empty()) {
     makefile.AddDefinition(prefix + "UNPARSED_ARGUMENTS",
-                           JoinList(unparsed, parseFromArgV).c_str());
+                           JoinList(unparsed, parseFromArgV));
   } else {
     makefile.RemoveDefinition(prefix + "UNPARSED_ARGUMENTS");
   }
 
   if (!keywordsMissingValues.empty()) {
-    makefile.AddDefinition(
-      prefix + "KEYWORDS_MISSING_VALUES",
-      cmJoin(cmMakeRange(keywordsMissingValues), ";").c_str());
+    makefile.AddDefinition(prefix + "KEYWORDS_MISSING_VALUES",
+                           cmJoin(cmMakeRange(keywordsMissingValues), ";"));
   } else {
     makefile.RemoveDefinition(prefix + "KEYWORDS_MISSING_VALUES");
   }
diff --git a/Source/cmParseArgumentsCommand.h b/Source/cmParseArgumentsCommand.h
index b8ba61d..692ea64 100644
--- a/Source/cmParseArgumentsCommand.h
+++ b/Source/cmParseArgumentsCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -21,7 +23,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmParseArgumentsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmParseArgumentsCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index c16a46f..92c80bb 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -283,6 +283,13 @@
   SELECT(POLICY, CMP0095,                                                     \
          "RPATH entries are properly escaped in the intermediary CMake "      \
          "install script.",                                                   \
+         3, 16, 0, cmPolicies::WARN)                                          \
+  SELECT(POLICY, CMP0096,                                                     \
+         "project() preserves leading zeros in version components.", 3, 16,   \
+         0, cmPolicies::WARN)                                                 \
+  SELECT(POLICY, CMP0097,                                                     \
+         "ExternalProject_Add with GIT_SUBMODULES \"\" initializes no "       \
+         "submodules.",                                                       \
          3, 16, 0, cmPolicies::WARN)
 
 #define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
diff --git a/Source/cmProjectCommand.cxx b/Source/cmProjectCommand.cxx
index 8615ecc..1159ef7 100644
--- a/Source/cmProjectCommand.cxx
+++ b/Source/cmProjectCommand.cxx
@@ -3,9 +3,12 @@
 #include "cmProjectCommand.h"
 
 #include "cmsys/RegularExpression.hxx"
+#include <array>
+#include <cstdio>
 #include <functional>
+#include <limits>
 #include <sstream>
-#include <stdio.h>
+#include <utility>
 
 #include "cmAlgorithms.h"
 #include "cmMakefile.h"
@@ -33,27 +36,21 @@
 
   this->Makefile->SetProjectName(projectName);
 
-  std::string bindir = projectName;
-  bindir += "_BINARY_DIR";
-  std::string srcdir = projectName;
-  srcdir += "_SOURCE_DIR";
-
   this->Makefile->AddCacheDefinition(
-    bindir, this->Makefile->GetCurrentBinaryDirectory().c_str(),
+    projectName + "_BINARY_DIR",
+    this->Makefile->GetCurrentBinaryDirectory().c_str(),
     "Value Computed by CMake", cmStateEnums::STATIC);
   this->Makefile->AddCacheDefinition(
-    srcdir, this->Makefile->GetCurrentSourceDirectory().c_str(),
+    projectName + "_SOURCE_DIR",
+    this->Makefile->GetCurrentSourceDirectory().c_str(),
     "Value Computed by CMake", cmStateEnums::STATIC);
 
-  bindir = "PROJECT_BINARY_DIR";
-  srcdir = "PROJECT_SOURCE_DIR";
+  this->Makefile->AddDefinition("PROJECT_BINARY_DIR",
+                                this->Makefile->GetCurrentBinaryDirectory());
+  this->Makefile->AddDefinition("PROJECT_SOURCE_DIR",
+                                this->Makefile->GetCurrentSourceDirectory());
 
-  this->Makefile->AddDefinition(
-    bindir, this->Makefile->GetCurrentBinaryDirectory().c_str());
-  this->Makefile->AddDefinition(
-    srcdir, this->Makefile->GetCurrentSourceDirectory().c_str());
-
-  this->Makefile->AddDefinition("PROJECT_NAME", projectName.c_str());
+  this->Makefile->AddDefinition("PROJECT_NAME", projectName);
 
   // Set the CMAKE_PROJECT_NAME variable to be the highest-level
   // project name in the tree. If there are two project commands
@@ -63,7 +60,7 @@
   // will work.
   if (!this->Makefile->GetDefinition("CMAKE_PROJECT_NAME") ||
       (this->Makefile->IsRootMakefile())) {
-    this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", projectName.c_str());
+    this->Makefile->AddDefinition("CMAKE_PROJECT_NAME", projectName);
     this->Makefile->AddCacheDefinition(
       "CMAKE_PROJECT_NAME", projectName.c_str(), "Value Computed by CMake",
       cmStateEnums::STATIC);
@@ -205,7 +202,7 @@
     languages.emplace_back("NONE");
   }
 
-  cmPolicies::PolicyStatus cmp0048 =
+  cmPolicies::PolicyStatus const cmp0048 =
     this->Makefile->GetPolicyStatus(cmPolicies::CMP0048);
   if (haveVersion) {
     // Set project VERSION variables to given values
@@ -220,64 +217,87 @@
     cmsys::RegularExpression vx(
       R"(^([0-9]+(\.[0-9]+(\.[0-9]+(\.[0-9]+)?)?)?)?$)");
     if (!vx.find(version)) {
-      std::string e = "VERSION \"" + version + "\" format invalid.";
+      std::string e = R"(VERSION ")" + version + R"(" format invalid.)";
       this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e);
       cmSystemTools::SetFatalErrorOccured();
       return true;
     }
 
-    std::string vs;
-    const char* sep = "";
-    char vb[4][64];
-    unsigned int v[4] = { 0, 0, 0, 0 };
-    int vc =
-      sscanf(version.c_str(), "%u.%u.%u.%u", &v[0], &v[1], &v[2], &v[3]);
-    for (int i = 0; i < 4; ++i) {
-      if (i < vc) {
-        sprintf(vb[i], "%u", v[i]);
-        vs += sep;
-        vs += vb[i];
-        sep = ".";
-      } else {
-        vb[i][0] = 0;
+    cmPolicies::PolicyStatus const cmp0096 =
+      this->Makefile->GetPolicyStatus(cmPolicies::CMP0096);
+
+    constexpr std::size_t MAX_VERSION_COMPONENTS = 4u;
+    std::string version_string;
+    std::array<std::string, MAX_VERSION_COMPONENTS> version_components;
+
+    if (cmp0096 == cmPolicies::OLD || cmp0096 == cmPolicies::WARN) {
+      char vb[MAX_VERSION_COMPONENTS][std::numeric_limits<unsigned>::digits10];
+      unsigned v[MAX_VERSION_COMPONENTS] = { 0, 0, 0, 0 };
+      const int vc = std::sscanf(version.c_str(), "%u.%u.%u.%u", &v[0], &v[1],
+                                 &v[2], &v[3]);
+      for (auto i = 0u; i < MAX_VERSION_COMPONENTS; ++i) {
+        if (int(i) < vc) {
+          std::sprintf(vb[i], "%u", v[i]);
+          version_string += &"."[std::size_t(i == 0)];
+          version_string += vb[i];
+          version_components[i] = vb[i];
+        } else {
+          vb[i][0] = '\x00';
+        }
+      }
+    } else {
+      // The regex above verified that we have a .-separated string of
+      // non-negative integer components.  Keep the original string.
+      version_string = std::move(version);
+      // Split the integer components.
+      auto components = cmSystemTools::SplitString(version_string, '.');
+      for (auto i = 0u; i < components.size(); ++i) {
+        version_components[i] = std::move(components[i]);
       }
     }
 
     std::string vv;
     vv = projectName + "_VERSION";
-    this->Makefile->AddDefinition("PROJECT_VERSION", vs.c_str());
-    this->Makefile->AddDefinition(vv, vs.c_str());
+    this->Makefile->AddDefinition("PROJECT_VERSION", version_string);
+    this->Makefile->AddDefinition(vv, version_string);
     vv = projectName + "_VERSION_MAJOR";
-    this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR", vb[0]);
-    this->Makefile->AddDefinition(vv, vb[0]);
+    this->Makefile->AddDefinition("PROJECT_VERSION_MAJOR",
+                                  version_components[0]);
+    this->Makefile->AddDefinition(vv, version_components[0]);
     vv = projectName + "_VERSION_MINOR";
-    this->Makefile->AddDefinition("PROJECT_VERSION_MINOR", vb[1]);
-    this->Makefile->AddDefinition(vv, vb[1]);
+    this->Makefile->AddDefinition("PROJECT_VERSION_MINOR",
+                                  version_components[1]);
+    this->Makefile->AddDefinition(vv, version_components[1]);
     vv = projectName + "_VERSION_PATCH";
-    this->Makefile->AddDefinition("PROJECT_VERSION_PATCH", vb[2]);
-    this->Makefile->AddDefinition(vv, vb[2]);
+    this->Makefile->AddDefinition("PROJECT_VERSION_PATCH",
+                                  version_components[2]);
+    this->Makefile->AddDefinition(vv, version_components[2]);
     vv = projectName + "_VERSION_TWEAK";
-    this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK", vb[3]);
-    this->Makefile->AddDefinition(vv, vb[3]);
+    this->Makefile->AddDefinition("PROJECT_VERSION_TWEAK",
+                                  version_components[3]);
+    this->Makefile->AddDefinition(vv, version_components[3]);
     // Also, try set top level variables
-    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION", vs.c_str());
-    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MAJOR", vb[0]);
-    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MINOR", vb[1]);
-    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_PATCH", vb[2]);
-    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_TWEAK", vb[3]);
+    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION", version_string.c_str());
+    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MAJOR",
+                            version_components[0].c_str());
+    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_MINOR",
+                            version_components[1].c_str());
+    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_PATCH",
+                            version_components[2].c_str());
+    TopLevelCMakeVarCondSet("CMAKE_PROJECT_VERSION_TWEAK",
+                            version_components[3].c_str());
   } else if (cmp0048 != cmPolicies::OLD) {
     // Set project VERSION variables to empty
-    std::vector<std::string> vv;
-    vv.emplace_back("PROJECT_VERSION");
-    vv.emplace_back("PROJECT_VERSION_MAJOR");
-    vv.emplace_back("PROJECT_VERSION_MINOR");
-    vv.emplace_back("PROJECT_VERSION_PATCH");
-    vv.emplace_back("PROJECT_VERSION_TWEAK");
-    vv.push_back(projectName + "_VERSION");
-    vv.push_back(projectName + "_VERSION_MAJOR");
-    vv.push_back(projectName + "_VERSION_MINOR");
-    vv.push_back(projectName + "_VERSION_PATCH");
-    vv.push_back(projectName + "_VERSION_TWEAK");
+    std::vector<std::string> vv = { "PROJECT_VERSION",
+                                    "PROJECT_VERSION_MAJOR",
+                                    "PROJECT_VERSION_MINOR",
+                                    "PROJECT_VERSION_PATCH",
+                                    "PROJECT_VERSION_TWEAK",
+                                    projectName + "_VERSION",
+                                    projectName + "_VERSION_MAJOR",
+                                    projectName + "_VERSION_MINOR",
+                                    projectName + "_VERSION_PATCH",
+                                    projectName + "_VERSION_TWEAK" };
     if (this->Makefile->IsRootMakefile()) {
       vv.emplace_back("CMAKE_PROJECT_VERSION");
       vv.emplace_back("CMAKE_PROJECT_VERSION_MAJOR");
@@ -287,7 +307,7 @@
     }
     std::string vw;
     for (std::string const& i : vv) {
-      const char* v = this->Makefile->GetDefinition(i);
+      const char* const v = this->Makefile->GetDefinition(i);
       if (v && *v) {
         if (cmp0048 == cmPolicies::WARN) {
           if (!injectedProjectCommand) {
@@ -307,20 +327,17 @@
     }
   }
 
-  this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description.c_str());
-  this->Makefile->AddDefinition(projectName + "_DESCRIPTION",
-                                description.c_str());
+  this->Makefile->AddDefinition("PROJECT_DESCRIPTION", description);
+  this->Makefile->AddDefinition(projectName + "_DESCRIPTION", description);
   TopLevelCMakeVarCondSet("CMAKE_PROJECT_DESCRIPTION", description.c_str());
 
-  this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage.c_str());
-  this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL",
-                                homepage.c_str());
+  this->Makefile->AddDefinition("PROJECT_HOMEPAGE_URL", homepage);
+  this->Makefile->AddDefinition(projectName + "_HOMEPAGE_URL", homepage);
   TopLevelCMakeVarCondSet("CMAKE_PROJECT_HOMEPAGE_URL", homepage.c_str());
 
   if (languages.empty()) {
     // if no language is specified do c and c++
-    languages.emplace_back("C");
-    languages.emplace_back("CXX");
+    languages = { "C", "CXX" };
   }
   this->Makefile->EnableLanguage(languages, false);
 
@@ -337,7 +354,7 @@
 
 bool cmProjectCommand::IncludeByVariable(const std::string& variable)
 {
-  const char* include = this->Makefile->GetDefinition(variable);
+  const char* const include = this->Makefile->GetDefinition(variable);
   if (!include) {
     return true;
   }
diff --git a/Source/cmProjectCommand.h b/Source/cmProjectCommand.h
index f1d03e7..8b9bcc8 100644
--- a/Source/cmProjectCommand.h
+++ b/Source/cmProjectCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -26,7 +28,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmProjectCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmProjectCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmQTWrapCPPCommand.cxx b/Source/cmQTWrapCPPCommand.cxx
index 9a764c6..f5852a9 100644
--- a/Source/cmQTWrapCPPCommand.cxx
+++ b/Source/cmQTWrapCPPCommand.cxx
@@ -89,6 +89,6 @@
   }
 
   // Store the final list of source files.
-  this->Makefile->AddDefinition(sourceList, sourceListValue.c_str());
+  this->Makefile->AddDefinition(sourceList, sourceListValue);
   return true;
 }
diff --git a/Source/cmQTWrapCPPCommand.h b/Source/cmQTWrapCPPCommand.h
index c1dcd54..88a2210 100644
--- a/Source/cmQTWrapCPPCommand.h
+++ b/Source/cmQTWrapCPPCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmQTWrapCPPCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmQTWrapCPPCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmQTWrapUICommand.cxx b/Source/cmQTWrapUICommand.cxx
index 2223e2d..361d7b3 100644
--- a/Source/cmQTWrapUICommand.cxx
+++ b/Source/cmQTWrapUICommand.cxx
@@ -132,7 +132,7 @@
   }
 
   // Store the final list of source files and headers.
-  this->Makefile->AddDefinition(sourceList, sourceListValue.c_str());
-  this->Makefile->AddDefinition(headerList, headerListValue.c_str());
+  this->Makefile->AddDefinition(sourceList, sourceListValue);
+  this->Makefile->AddDefinition(headerList, headerListValue);
   return true;
 }
diff --git a/Source/cmQTWrapUICommand.h b/Source/cmQTWrapUICommand.h
index 15cab40..6a346d4 100644
--- a/Source/cmQTWrapUICommand.h
+++ b/Source/cmQTWrapUICommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmQTWrapUICommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmQTWrapUICommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index ef8a56b..f172b77 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -4,7 +4,6 @@
 #include "cmQtAutoGen.h"
 #include "cmQtAutoGenInitializer.h"
 
-#include "cmAlgorithms.h"
 #include "cmCustomCommandLines.h"
 #include "cmDuration.h"
 #include "cmGeneratorTarget.h"
@@ -17,9 +16,10 @@
 #include "cmSystemTools.h"
 #include "cmTarget.h"
 
-#include <memory>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 cmQtAutoGenGlobalInitializer::Keywords::Keywords()
   : AUTOMOC("AUTOMOC")
   , AUTOUIC("AUTOUIC")
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 83a1bc4..4b12419 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -38,6 +38,8 @@
 #include <utility>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 static std::size_t GetParallelCPUCount()
 {
   static std::size_t count = 0;
diff --git a/Source/cmQtAutoGenerator.cxx b/Source/cmQtAutoGenerator.cxx
index 3a3162d..2516d84 100644
--- a/Source/cmQtAutoGenerator.cxx
+++ b/Source/cmQtAutoGenerator.cxx
@@ -5,7 +5,8 @@
 
 #include "cmsys/FStream.hxx"
 
-#include "cmAlgorithms.h"
+#include "cm_memory.hxx"
+
 #include "cmGlobalGenerator.h"
 #include "cmMakefile.h"
 #include "cmState.h"
@@ -14,8 +15,6 @@
 #include "cmSystemTools.h"
 #include "cmake.h"
 
-#include <memory>
-
 cmQtAutoGenerator::Logger::Logger()
 {
   // Initialize logger
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 889f47d..44d2db0 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -5,11 +5,12 @@
 #include <algorithm>
 #include <array>
 #include <list>
-#include <memory>
 #include <set>
 #include <sstream>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmCryptoHash.h"
 #include "cmGeneratedFileStream.h"
diff --git a/Source/cmRemoveCommand.cxx b/Source/cmRemoveCommand.cxx
index a64ad8c..d0ee4d4 100644
--- a/Source/cmRemoveCommand.cxx
+++ b/Source/cmRemoveCommand.cxx
@@ -52,7 +52,7 @@
   }
 
   // add the definition
-  this->Makefile->AddDefinition(variable, value.c_str());
+  this->Makefile->AddDefinition(variable, value);
 
   return true;
 }
diff --git a/Source/cmRemoveCommand.h b/Source/cmRemoveCommand.h
index 7b11849..088d8ad 100644
--- a/Source/cmRemoveCommand.h
+++ b/Source/cmRemoveCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmRemoveCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmRemoveCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmRemoveDefinitionsCommand.h b/Source/cmRemoveDefinitionsCommand.h
index a5cb204..85d01d4 100644
--- a/Source/cmRemoveDefinitionsCommand.h
+++ b/Source/cmRemoveDefinitionsCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -25,7 +27,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmRemoveDefinitionsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmRemoveDefinitionsCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmReturnCommand.cxx b/Source/cmReturnCommand.cxx
index ceea8b4..5905669 100644
--- a/Source/cmReturnCommand.cxx
+++ b/Source/cmReturnCommand.cxx
@@ -5,8 +5,8 @@
 #include "cmExecutionStatus.h"
 
 // cmReturnCommand
-bool cmReturnCommand::InitialPass(std::vector<std::string> const&,
-                                  cmExecutionStatus& status)
+bool cmReturnCommand(std::vector<std::string> const&,
+                     cmExecutionStatus& status)
 {
   status.SetReturnInvoked();
   return true;
diff --git a/Source/cmReturnCommand.h b/Source/cmReturnCommand.h
index ef39614..2404a36 100644
--- a/Source/cmReturnCommand.h
+++ b/Source/cmReturnCommand.h
@@ -8,29 +8,10 @@
 #include <string>
 #include <vector>
 
-#include "cmCommand.h"
-
 class cmExecutionStatus;
 
-/** \class cmReturnCommand
- * \brief Return from a directory or function
- *
- * cmReturnCommand returns from a directory or function
- */
-class cmReturnCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  cmCommand* Clone() override { return new cmReturnCommand; }
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-};
+/// Return from a directory or function
+bool cmReturnCommand(std::vector<std::string> const& args,
+                     cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmRuntimeDependencyArchive.cxx b/Source/cmRuntimeDependencyArchive.cxx
index a1d1f95..45aff69 100644
--- a/Source/cmRuntimeDependencyArchive.cxx
+++ b/Source/cmRuntimeDependencyArchive.cxx
@@ -3,7 +3,6 @@
 
 #include "cmRuntimeDependencyArchive.h"
 
-#include "cmAlgorithms.h"
 #include "cmBinUtilsLinuxELFLinker.h"
 #include "cmBinUtilsMacOSMachOLinker.h"
 #include "cmBinUtilsWindowsPELinker.h"
@@ -27,6 +26,8 @@
 #include <utility>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #if defined(_WIN32)
 static void AddVisualStudioPath(std::vector<std::string>& paths,
                                 const std::string& prefix,
diff --git a/Source/cmSeparateArgumentsCommand.cxx b/Source/cmSeparateArgumentsCommand.cxx
index 28cbdc0..ab4a0c7 100644
--- a/Source/cmSeparateArgumentsCommand.cxx
+++ b/Source/cmSeparateArgumentsCommand.cxx
@@ -69,7 +69,7 @@
     if (const char* def = this->Makefile->GetDefinition(var)) {
       std::string value = def;
       std::replace(value.begin(), value.end(), ' ', ';');
-      this->Makefile->AddDefinition(var, value.c_str());
+      this->Makefile->AddDefinition(var, value);
     }
   } else {
     // Parse the command line.
@@ -97,7 +97,7 @@
         value += si;
       }
     }
-    this->Makefile->AddDefinition(var, value.c_str());
+    this->Makefile->AddDefinition(var, value);
   }
 
   return true;
diff --git a/Source/cmSeparateArgumentsCommand.h b/Source/cmSeparateArgumentsCommand.h
index 988ad23..76e2002 100644
--- a/Source/cmSeparateArgumentsCommand.h
+++ b/Source/cmSeparateArgumentsCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmSeparateArgumentsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmSeparateArgumentsCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
index 1903fd9..9df1883 100644
--- a/Source/cmServer.cxx
+++ b/Source/cmServer.cxx
@@ -2,7 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmServer.h"
 
-#include "cmAlgorithms.h"
 #include "cmConnection.h"
 #include "cmFileMonitor.h"
 #include "cmJsonObjectDictionary.h"
@@ -18,10 +17,11 @@
 #include <cassert>
 #include <cstdint>
 #include <iostream>
-#include <memory>
 #include <mutex>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 void on_signal(uv_signal_t* signal, int signum)
 {
   auto conn = static_cast<cmServerBase*>(signal->data);
diff --git a/Source/cmServerProtocol.cxx b/Source/cmServerProtocol.cxx
index 558391f..c5de742 100644
--- a/Source/cmServerProtocol.cxx
+++ b/Source/cmServerProtocol.cxx
@@ -2,7 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmServerProtocol.h"
 
-#include "cmAlgorithms.h"
 #include "cmExternalMakefileProjectGenerator.h"
 #include "cmFileMonitor.h"
 #include "cmGlobalGenerator.h"
@@ -19,11 +18,12 @@
 #include <algorithm>
 #include <cassert>
 #include <functional>
-#include <memory>
 #include <string>
 #include <utility>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 // Get rid of some windows macros:
 #undef max
 
diff --git a/Source/cmSetCommand.cxx b/Source/cmSetCommand.cxx
index 41555e8..b36878c 100644
--- a/Source/cmSetCommand.cxx
+++ b/Source/cmSetCommand.cxx
@@ -154,7 +154,7 @@
                                        type, force);
   } else {
     // add the definition
-    this->Makefile->AddDefinition(variable, value.c_str());
+    this->Makefile->AddDefinition(variable, value);
   }
   return true;
 }
diff --git a/Source/cmSetCommand.h b/Source/cmSetCommand.h
index 76e3eae..1c5a435 100644
--- a/Source/cmSetCommand.h
+++ b/Source/cmSetCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmSetCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmSetCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmSetDirectoryPropertiesCommand.h b/Source/cmSetDirectoryPropertiesCommand.h
index 473347c..5416127 100644
--- a/Source/cmSetDirectoryPropertiesCommand.h
+++ b/Source/cmSetDirectoryPropertiesCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -16,7 +18,10 @@
 class cmSetDirectoryPropertiesCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmSetDirectoryPropertiesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmSetDirectoryPropertiesCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmSetPropertyCommand.h b/Source/cmSetPropertyCommand.h
index f1126bb..4051e48 100644
--- a/Source/cmSetPropertyCommand.h
+++ b/Source/cmSetPropertyCommand.h
@@ -9,6 +9,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -22,7 +24,10 @@
 public:
   cmSetPropertyCommand();
 
-  cmCommand* Clone() override { return new cmSetPropertyCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmSetPropertyCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmSetSourceFilesPropertiesCommand.h b/Source/cmSetSourceFilesPropertiesCommand.h
index afb19f6..6fd6c41 100644
--- a/Source/cmSetSourceFilesPropertiesCommand.h
+++ b/Source/cmSetSourceFilesPropertiesCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -16,7 +18,10 @@
 class cmSetSourceFilesPropertiesCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmSetSourceFilesPropertiesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmSetSourceFilesPropertiesCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmSetTargetPropertiesCommand.h b/Source/cmSetTargetPropertiesCommand.h
index c9755da..7e4606e 100644
--- a/Source/cmSetTargetPropertiesCommand.h
+++ b/Source/cmSetTargetPropertiesCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -16,7 +18,10 @@
 class cmSetTargetPropertiesCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmSetTargetPropertiesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmSetTargetPropertiesCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmSetTestsPropertiesCommand.h b/Source/cmSetTestsPropertiesCommand.h
index 84b2645..d73e95a 100644
--- a/Source/cmSetTestsPropertiesCommand.h
+++ b/Source/cmSetTestsPropertiesCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -16,7 +18,10 @@
 class cmSetTestsPropertiesCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmSetTestsPropertiesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmSetTestsPropertiesCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmSiteNameCommand.h b/Source/cmSiteNameCommand.h
index 2d8dc17..0190abb 100644
--- a/Source/cmSiteNameCommand.h
+++ b/Source/cmSiteNameCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmSiteNameCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmSiteNameCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmSourceFileLocation.cxx b/Source/cmSourceFileLocation.cxx
index acacba2..d887627 100644
--- a/Source/cmSourceFileLocation.cxx
+++ b/Source/cmSourceFileLocation.cxx
@@ -146,8 +146,7 @@
   // adding an extension.
   if (!(this->Name.size() > loc.Name.size() &&
         this->Name[loc.Name.size()] == '.' &&
-        cmHasLiteralPrefixImpl(this->Name.c_str(), loc.Name.c_str(),
-                               loc.Name.size()))) {
+        cmHasPrefix(this->Name, loc.Name))) {
     return false;
   }
 
diff --git a/Source/cmSourceGroupCommand.h b/Source/cmSourceGroupCommand.h
index ec5ad32..eec4ec0 100644
--- a/Source/cmSourceGroupCommand.h
+++ b/Source/cmSourceGroupCommand.h
@@ -9,6 +9,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -25,7 +27,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmSourceGroupCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmSourceGroupCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmState.cxx b/Source/cmState.cxx
index 587cda5..6f9c935 100644
--- a/Source/cmState.cxx
+++ b/Source/cmState.cxx
@@ -5,20 +5,24 @@
 #include "cmsys/RegularExpression.hxx"
 #include <algorithm>
 #include <assert.h>
+#include <stdlib.h>
 #include <string.h>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmCacheManager.h"
 #include "cmCommand.h"
 #include "cmDefinitions.h"
 #include "cmDisallowedCommand.h"
+#include "cmExecutionStatus.h"
 #include "cmGlobVerificationManager.h"
 #include "cmListFileCache.h"
+#include "cmMakefile.h"
 #include "cmStatePrivate.h"
 #include "cmStateSnapshot.h"
 #include "cmSystemTools.h"
-#include "cmUnexpectedCommand.h"
 #include "cmake.h"
 
 cmState::cmState()
@@ -27,11 +31,7 @@
   this->GlobVerificationManager = cm::make_unique<cmGlobVerificationManager>();
 }
 
-cmState::~cmState()
-{
-  cmDeleteAll(this->BuiltinCommands);
-  cmDeleteAll(this->ScriptedCommands);
-}
+cmState::~cmState() = default;
 
 const char* cmState::GetTargetTypeName(cmStateEnums::TargetType targetType)
 {
@@ -308,8 +308,8 @@
     pos->Parent = this->VarTree.Root();
     pos->Root = this->VarTree.Root();
 
-    pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir.c_str());
-    pos->Vars->Set("CMAKE_BINARY_DIR", binDir.c_str());
+    pos->Vars->Set("CMAKE_SOURCE_DIR", srcDir);
+    pos->Vars->Set("CMAKE_BINARY_DIR", binDir);
   }
 
   this->DefineProperty("RULE_LAUNCH_COMPILE", cmProperty::DIRECTORY, "", "",
@@ -419,61 +419,82 @@
   this->IsGeneratorMultiConfig = b;
 }
 
-void cmState::AddBuiltinCommand(std::string const& name, cmCommand* command)
+void cmState::AddBuiltinCommand(std::string const& name,
+                                std::unique_ptr<cmCommand> command)
+{
+  this->AddBuiltinCommand(name, cmLegacyCommandWrapper(std::move(command)));
+}
+
+void cmState::AddBuiltinCommand(std::string const& name, Command command)
 {
   assert(name == cmSystemTools::LowerCase(name));
   assert(this->BuiltinCommands.find(name) == this->BuiltinCommands.end());
-  this->BuiltinCommands.insert(std::make_pair(name, command));
+  this->BuiltinCommands.emplace(name, std::move(command));
 }
 
-void cmState::AddDisallowedCommand(std::string const& name, cmCommand* command,
+void cmState::AddBuiltinCommand(std::string const& name,
+                                BuiltinCommand command)
+{
+  this->AddBuiltinCommand(
+    name,
+    [command](const std::vector<cmListFileArgument>& args,
+              cmExecutionStatus& status) -> bool {
+      std::vector<std::string> expandedArguments;
+      if (!status.GetMakefile().ExpandArguments(args, expandedArguments)) {
+        // There was an error expanding arguments.  It was already
+        // reported, so we can skip this command without error.
+        return true;
+      }
+      return command(expandedArguments, status);
+    });
+}
+
+void cmState::AddDisallowedCommand(std::string const& name,
+                                   std::unique_ptr<cmCommand> command,
                                    cmPolicies::PolicyID policy,
                                    const char* message)
 {
-  this->AddBuiltinCommand(name,
-                          new cmDisallowedCommand(command, policy, message));
+  this->AddBuiltinCommand(
+    name,
+    cm::make_unique<cmDisallowedCommand>(std::move(command), policy, message));
 }
 
 void cmState::AddUnexpectedCommand(std::string const& name, const char* error)
 {
-  this->AddBuiltinCommand(name, new cmUnexpectedCommand(name, error));
+  this->AddBuiltinCommand(
+    name,
+    [name, error](std::vector<cmListFileArgument> const&,
+                  cmExecutionStatus& status) -> bool {
+      const char* versionValue =
+        status.GetMakefile().GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
+      if (name == "endif" && (!versionValue || atof(versionValue) <= 1.4)) {
+        return true;
+      }
+      status.SetError(error);
+      return false;
+    });
 }
 
-void cmState::AddScriptedCommand(std::string const& name, cmCommand* command)
+void cmState::AddScriptedCommand(std::string const& name, Command command)
 {
   std::string sName = cmSystemTools::LowerCase(name);
 
   // if the command already exists, give a new name to the old command.
-  if (cmCommand* oldCmd = this->GetCommand(sName)) {
-    std::string const newName = "_" + sName;
-    std::map<std::string, cmCommand*>::iterator pos =
-      this->ScriptedCommands.find(newName);
-    if (pos != this->ScriptedCommands.end()) {
-      delete pos->second;
-      this->ScriptedCommands.erase(pos);
-    }
-    this->ScriptedCommands.insert(std::make_pair(newName, oldCmd->Clone()));
+  if (Command oldCmd = this->GetCommand(sName)) {
+    this->ScriptedCommands["_" + sName] = oldCmd;
   }
 
-  // if the command already exists, free the old one
-  std::map<std::string, cmCommand*>::iterator pos =
-    this->ScriptedCommands.find(sName);
-  if (pos != this->ScriptedCommands.end()) {
-    delete pos->second;
-    this->ScriptedCommands.erase(pos);
-  }
-  this->ScriptedCommands.insert(std::make_pair(sName, command));
+  this->ScriptedCommands[sName] = std::move(command);
 }
 
-cmCommand* cmState::GetCommand(std::string const& name) const
+cmState::Command cmState::GetCommand(std::string const& name) const
 {
   return GetCommandByExactName(cmSystemTools::LowerCase(name));
 }
 
-cmCommand* cmState::GetCommandByExactName(std::string const& name) const
+cmState::Command cmState::GetCommandByExactName(std::string const& name) const
 {
-  std::map<std::string, cmCommand*>::const_iterator pos;
-  pos = this->ScriptedCommands.find(name);
+  auto pos = this->ScriptedCommands.find(name);
   if (pos != this->ScriptedCommands.end()) {
     return pos->second;
   }
@@ -504,16 +525,11 @@
 void cmState::RemoveBuiltinCommand(std::string const& name)
 {
   assert(name == cmSystemTools::LowerCase(name));
-  std::map<std::string, cmCommand*>::iterator i =
-    this->BuiltinCommands.find(name);
-  assert(i != this->BuiltinCommands.end());
-  delete i->second;
-  this->BuiltinCommands.erase(i);
+  this->BuiltinCommands.erase(name);
 }
 
 void cmState::RemoveUserDefinedCommands()
 {
-  cmDeleteAll(this->ScriptedCommands);
   this->ScriptedCommands.clear();
 }
 
diff --git a/Source/cmState.h b/Source/cmState.h
index 0649ace..8847f3b 100644
--- a/Source/cmState.h
+++ b/Source/cmState.h
@@ -5,6 +5,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <functional>
 #include <map>
 #include <memory>
 #include <set>
@@ -27,6 +28,7 @@
 class cmPropertyDefinition;
 class cmStateSnapshot;
 class cmMessenger;
+class cmExecutionStatus;
 
 class cmState
 {
@@ -141,16 +143,25 @@
   bool GetIsGeneratorMultiConfig() const;
   void SetIsGeneratorMultiConfig(bool b);
 
-  // Returns a command from its name, case insensitive, or nullptr
-  cmCommand* GetCommand(std::string const& name) const;
-  // Returns a command from its name, or nullptr
-  cmCommand* GetCommandByExactName(std::string const& name) const;
+  using Command = std::function<bool(std::vector<cmListFileArgument> const&,
+                                     cmExecutionStatus&)>;
+  using BuiltinCommand = bool (*)(std::vector<std::string> const&,
+                                  cmExecutionStatus&);
 
-  void AddBuiltinCommand(std::string const& name, cmCommand* command);
-  void AddDisallowedCommand(std::string const& name, cmCommand* command,
+  // Returns a command from its name, case insensitive, or nullptr
+  Command GetCommand(std::string const& name) const;
+  // Returns a command from its name, or nullptr
+  Command GetCommandByExactName(std::string const& name) const;
+
+  void AddBuiltinCommand(std::string const& name,
+                         std::unique_ptr<cmCommand> command);
+  void AddBuiltinCommand(std::string const& name, Command command);
+  void AddBuiltinCommand(std::string const& name, BuiltinCommand command);
+  void AddDisallowedCommand(std::string const& name,
+                            std::unique_ptr<cmCommand> command,
                             cmPolicies::PolicyID policy, const char* message);
   void AddUnexpectedCommand(std::string const& name, const char* error);
-  void AddScriptedCommand(std::string const& name, cmCommand* command);
+  void AddScriptedCommand(std::string const& name, Command command);
   void RemoveBuiltinCommand(std::string const& name);
   void RemoveUserDefinedCommands();
   std::vector<std::string> GetCommandNames() const;
@@ -209,8 +220,8 @@
 
   std::map<cmProperty::ScopeType, cmPropertyDefinitionMap> PropertyDefinitions;
   std::vector<std::string> EnabledLanguages;
-  std::map<std::string, cmCommand*> BuiltinCommands;
-  std::map<std::string, cmCommand*> ScriptedCommands;
+  std::map<std::string, Command> BuiltinCommands;
+  std::map<std::string, Command> ScriptedCommands;
   cmPropertyMap GlobalProperties;
   std::unique_ptr<cmCacheManager> CacheManager;
   std::unique_ptr<cmGlobVerificationManager> GlobVerificationManager;
diff --git a/Source/cmStateSnapshot.cxx b/Source/cmStateSnapshot.cxx
index 63bec71..110ec56 100644
--- a/Source/cmStateSnapshot.cxx
+++ b/Source/cmStateSnapshot.cxx
@@ -222,14 +222,14 @@
 }
 
 void cmStateSnapshot::SetDefinition(std::string const& name,
-                                    std::string const& value)
+                                    cm::string_view value)
 {
-  this->Position->Vars->Set(name, value.c_str());
+  this->Position->Vars->Set(name, value);
 }
 
 void cmStateSnapshot::RemoveDefinition(std::string const& name)
 {
-  this->Position->Vars->Set(name, nullptr);
+  this->Position->Vars->Unset(name);
 }
 
 std::vector<std::string> cmStateSnapshot::UnusedKeys() const
@@ -264,7 +264,11 @@
   cmDefinitions::Raise(var, this->Position->Vars, this->Position->Root);
 
   // Now update the definition in the parent scope.
-  this->Position->Parent->Set(var, varDef);
+  if (varDef) {
+    this->Position->Parent->Set(var, varDef);
+  } else {
+    this->Position->Parent->Unset(var);
+  }
   return true;
 }
 
diff --git a/Source/cmStateSnapshot.h b/Source/cmStateSnapshot.h
index c315f48..da39127 100644
--- a/Source/cmStateSnapshot.h
+++ b/Source/cmStateSnapshot.h
@@ -9,6 +9,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_string_view.hxx"
+
 #include "cmLinkedTree.h"
 #include "cmPolicies.h"
 #include "cmStateTypes.h"
@@ -24,7 +26,7 @@
 
   std::string const* GetDefinition(std::string const& name) const;
   bool IsInitialized(std::string const& name) const;
-  void SetDefinition(std::string const& name, std::string const& value);
+  void SetDefinition(std::string const& name, cm::string_view value);
   void RemoveDefinition(std::string const& name);
   std::vector<std::string> UnusedKeys() const;
   std::vector<std::string> ClosureKeys() const;
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index 10ccac0..259d92a 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -8,7 +8,6 @@
 #include <algorithm>
 #include <ctype.h>
 #include <iterator>
-#include <memory>
 #include <sstream>
 #include <stdio.h>
 #include <stdlib.h>
@@ -124,7 +123,7 @@
   std::unique_ptr<cmCryptoHash> hash(cmCryptoHash::New(args[0].c_str()));
   if (hash) {
     std::string out = hash->HashString(args[2]);
-    this->Makefile->AddDefinition(args[1], out.c_str());
+    this->Makefile->AddDefinition(args[1], out);
     return true;
   }
   return false;
@@ -154,7 +153,7 @@
   }
 
   // Store the output in the provided variable.
-  this->Makefile->AddDefinition(outvar, output.c_str());
+  this->Makefile->AddDefinition(outvar, output);
   return true;
 }
 
@@ -180,7 +179,7 @@
     }
   }
   // Store the output in the provided variable.
-  this->Makefile->AddDefinition(outvar, output.c_str());
+  this->Makefile->AddDefinition(outvar, output);
   return true;
 }
 
@@ -217,7 +216,7 @@
   this->Makefile->ConfigureString(args[1], output, atOnly, escapeQuotes);
 
   // Store the output in the provided variable.
-  this->Makefile->AddDefinition(args[2], output.c_str());
+  this->Makefile->AddDefinition(args[2], output);
 
   return true;
 }
@@ -296,7 +295,7 @@
   }
 
   // Store the output in the provided variable.
-  this->Makefile->AddDefinition(outvar, output.c_str());
+  this->Makefile->AddDefinition(outvar, output);
   return true;
 }
 
@@ -343,7 +342,7 @@
   }
 
   // Store the output in the provided variable.
-  this->Makefile->AddDefinition(outvar, output.c_str());
+  this->Makefile->AddDefinition(outvar, output);
   return true;
 }
 
@@ -384,7 +383,7 @@
   }
 
   // Store the output in the provided variable.
-  this->Makefile->AddDefinition(outvar, output.c_str());
+  this->Makefile->AddDefinition(outvar, output);
   return true;
 }
 
@@ -431,7 +430,7 @@
   if (std::string::npos != pos) {
     std::ostringstream s;
     s << pos;
-    this->Makefile->AddDefinition(outvar, s.str().c_str());
+    this->Makefile->AddDefinition(outvar, s.str());
     return true;
   }
 
@@ -506,7 +505,7 @@
   cmsys::SystemTools::ReplaceString(input, matchExpression.c_str(),
                                     replaceExpression.c_str());
 
-  this->Makefile->AddDefinition(variableName, input.c_str());
+  this->Makefile->AddDefinition(variableName, input);
   return true;
 }
 
@@ -539,8 +538,7 @@
     return false;
   }
 
-  this->Makefile->AddDefinition(variableName,
-                                stringValue.substr(begin, end).c_str());
+  this->Makefile->AddDefinition(variableName, stringValue.substr(begin, end));
   return true;
 }
 
@@ -582,7 +580,7 @@
     value = oldValue;
   }
   value += cmJoin(cmMakeRange(args).advance(2), std::string());
-  this->Makefile->AddDefinition(variable, value.c_str());
+  this->Makefile->AddDefinition(variable, value);
   return true;
 }
 
@@ -606,7 +604,7 @@
   if (oldValue) {
     value += oldValue;
   }
-  this->Makefile->AddDefinition(variable, value.c_str());
+  this->Makefile->AddDefinition(variable, value);
   return true;
 }
 
@@ -638,7 +636,7 @@
   // both `CONCAT` and `JOIN` sub-commands.
   std::string value = cmJoin(cmMakeRange(args).advance(varIdx + 1), glue);
 
-  this->Makefile->AddDefinition(variableName, value.c_str());
+  this->Makefile->AddDefinition(variableName, value);
   return true;
 }
 
@@ -654,7 +652,7 @@
   const std::string& variableName = args[2];
 
   this->Makefile->AddDefinition(variableName,
-                                cmSystemTools::MakeCidentifier(input).c_str());
+                                cmSystemTools::MakeCidentifier(input));
   return true;
 }
 
@@ -673,7 +671,7 @@
 
   const std::string& variableName = args[2];
 
-  this->Makefile->AddDefinition(variableName, result.c_str());
+  this->Makefile->AddDefinition(variableName, result);
   return true;
 }
 
@@ -712,8 +710,8 @@
     outLength = endPos - startPos + 1;
   }
 
-  this->Makefile->AddDefinition(
-    variableName, stringValue.substr(startPos, outLength).c_str());
+  this->Makefile->AddDefinition(variableName,
+                                stringValue.substr(startPos, outLength));
   return true;
 }
 
@@ -766,7 +764,7 @@
       break;
   }
 
-  this->Makefile->AddDefinition(variableName, result.c_str());
+  this->Makefile->AddDefinition(variableName, result);
   return true;
 }
 
@@ -872,7 +870,7 @@
 
   cmTimestamp timestamp;
   std::string result = timestamp.CurrentTime(formatString, utcFlag);
-  this->Makefile->AddDefinition(outputVariable, result.c_str());
+  this->Makefile->AddDefinition(outputVariable, result);
 
   return true;
 }
@@ -955,7 +953,7 @@
     uuid = cmSystemTools::UpperCase(uuid);
   }
 
-  this->Makefile->AddDefinition(outputVariable, uuid.c_str());
+  this->Makefile->AddDefinition(outputVariable, uuid);
   return true;
 #else
   std::ostringstream e;
diff --git a/Source/cmStringCommand.h b/Source/cmStringCommand.h
index acde605..f48ea17 100644
--- a/Source/cmStringCommand.h
+++ b/Source/cmStringCommand.h
@@ -9,6 +9,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmStringCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmStringCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmSubdirCommand.h b/Source/cmSubdirCommand.h
index adab757..3499c46 100644
--- a/Source/cmSubdirCommand.h
+++ b/Source/cmSubdirCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -25,7 +27,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmSubdirCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmSubdirCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmSubdirDependsCommand.h b/Source/cmSubdirDependsCommand.h
index 2db28c6..64c28b9 100644
--- a/Source/cmSubdirDependsCommand.h
+++ b/Source/cmSubdirDependsCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,7 +17,10 @@
 class cmSubdirDependsCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmSubdirDependsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmSubdirDependsCommand>();
+  }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
 };
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 723f280..3ba3640 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -282,115 +282,85 @@
   cmSystemTools::Error(m);
 }
 
-bool cmSystemTools::IsInternallyOn(const char* val)
+bool cmSystemTools::IsInternallyOn(cm::string_view val)
 {
-  if (!val) {
-    return false;
-  }
-  std::string v = val;
-  if (v.size() > 4) {
-    return false;
-  }
-
-  for (char& c : v) {
-    c = static_cast<char>(toupper(c));
-  }
-  return v == "I_ON";
+  return (val.size() == 4) &&           //
+    (val[0] == 'I' || val[0] == 'i') && //
+    (val[1] == '_') &&                  //
+    (val[2] == 'O' || val[2] == 'o') && //
+    (val[3] == 'N' || val[3] == 'n');
 }
 
-bool cmSystemTools::IsOn(const char* val)
+bool cmSystemTools::IsOn(cm::string_view val)
 {
-  if (!val) {
-    return false;
+  switch (val.size()) {
+    case 1:
+      return val[0] == '1' || val[0] == 'Y' || val[0] == 'y';
+    case 2:
+      return                                //
+        (val[0] == 'O' || val[0] == 'o') && //
+        (val[1] == 'N' || val[1] == 'n');
+    case 3:
+      return                                //
+        (val[0] == 'Y' || val[0] == 'y') && //
+        (val[1] == 'E' || val[1] == 'e') && //
+        (val[2] == 'S' || val[2] == 's');
+    case 4:
+      return                                //
+        (val[0] == 'T' || val[0] == 't') && //
+        (val[1] == 'R' || val[1] == 'r') && //
+        (val[2] == 'U' || val[2] == 'u') && //
+        (val[3] == 'E' || val[3] == 'e');
+    default:
+      break;
   }
-  /* clang-format off */
-  // "1"
-  if (val[0] == '1' && val[1] == '\0') {
-    return true;
-  }
-  // "ON"
-  if ((val[0] == 'O' || val[0] == 'o') &&
-      (val[1] == 'N' || val[1] == 'n') && val[2] == '\0') {
-    return true;
-  }
-  // "Y", "YES"
-  if ((val[0] == 'Y' || val[0] == 'y') && (val[1] == '\0' || (
-      (val[1] == 'E' || val[1] == 'e') &&
-      (val[2] == 'S' || val[2] == 's') && val[3] == '\0'))) {
-    return true;
-  }
-  // "TRUE"
-  if ((val[0] == 'T' || val[0] == 't') &&
-      (val[1] == 'R' || val[1] == 'r') &&
-      (val[2] == 'U' || val[2] == 'u') &&
-      (val[3] == 'E' || val[3] == 'e') && val[4] == '\0') {
-    return true;
-  }
-  /* clang-format on */
+
   return false;
 }
 
-bool cmSystemTools::IsOn(const std::string& val)
+bool cmSystemTools::IsNOTFOUND(cm::string_view val)
 {
-  return cmSystemTools::IsOn(val.c_str());
+  return (val == "NOTFOUND") || cmHasLiteralSuffix(val, "-NOTFOUND");
 }
 
-bool cmSystemTools::IsNOTFOUND(const char* val)
+bool cmSystemTools::IsOff(cm::string_view val)
 {
-  if (strcmp(val, "NOTFOUND") == 0) {
-    return true;
+  switch (val.size()) {
+    case 0:
+      return true;
+    case 1:
+      return val[0] == '0' || val[0] == 'N' || val[0] == 'n';
+    case 2:
+      return                                //
+        (val[0] == 'N' || val[0] == 'n') && //
+        (val[1] == 'O' || val[1] == 'o');
+    case 3:
+      return                                //
+        (val[0] == 'O' || val[0] == 'o') && //
+        (val[1] == 'F' || val[1] == 'f') && //
+        (val[2] == 'F' || val[2] == 'f');
+    case 5:
+      return                                //
+        (val[0] == 'F' || val[0] == 'f') && //
+        (val[1] == 'A' || val[1] == 'a') && //
+        (val[2] == 'L' || val[2] == 'l') && //
+        (val[3] == 'S' || val[3] == 's') && //
+        (val[4] == 'E' || val[4] == 'e');
+    case 6:
+      return                                //
+        (val[0] == 'I' || val[0] == 'i') && //
+        (val[1] == 'G' || val[1] == 'g') && //
+        (val[2] == 'N' || val[2] == 'n') && //
+        (val[3] == 'O' || val[3] == 'o') && //
+        (val[4] == 'R' || val[4] == 'r') && //
+        (val[5] == 'E' || val[5] == 'e');
+    default:
+      break;
   }
-  return cmHasLiteralSuffix(val, "-NOTFOUND");
-}
 
-bool cmSystemTools::IsOff(const char* val)
-{
-  // ""
-  if (!val || val[0] == '\0') {
-    return true;
-  }
-  /* clang-format off */
-  // "0"
-  if (val[0] == '0' && val[1] == '\0') {
-    return true;
-  }
-  // "OFF"
-  if ((val[0] == 'O' || val[0] == 'o') &&
-      (val[1] == 'F' || val[1] == 'f') &&
-      (val[2] == 'F' || val[2] == 'f') && val[3] == '\0') {
-    return true;
-  }
-  // "N", "NO"
-  if ((val[0] == 'N' || val[0] == 'n') && (val[1] == '\0' || (
-      (val[1] == 'O' || val[1] == 'o') && val[2] == '\0'))) {
-    return true;
-  }
-  // "FALSE"
-  if ((val[0] == 'F' || val[0] == 'f') &&
-      (val[1] == 'A' || val[1] == 'a') &&
-      (val[2] == 'L' || val[2] == 'l') &&
-      (val[3] == 'S' || val[3] == 's') &&
-      (val[4] == 'E' || val[4] == 'e') && val[5] == '\0') {
-    return true;
-  }
-  // "IGNORE"
-  if ((val[0] == 'I' || val[0] == 'i') &&
-      (val[1] == 'G' || val[1] == 'g') &&
-      (val[2] == 'N' || val[2] == 'n') &&
-      (val[3] == 'O' || val[3] == 'o') &&
-      (val[4] == 'R' || val[4] == 'r') &&
-      (val[5] == 'E' || val[5] == 'e') && val[6] == '\0') {
-    return true;
-  }
-  /* clang-format on */
   return cmSystemTools::IsNOTFOUND(val);
 }
 
-bool cmSystemTools::IsOff(const std::string& val)
-{
-  return cmSystemTools::IsOff(val.c_str());
-}
-
 void cmSystemTools::ParseWindowsCommandLine(const char* command,
                                             std::vector<std::string>& args)
 {
@@ -2397,7 +2367,8 @@
 #if defined(CMAKE_USE_ELF_PARSER)
 bool cmSystemTools::ChangeRPath(std::string const& file,
                                 std::string const& oldRPath,
-                                std::string const& newRPath, std::string* emsg,
+                                std::string const& newRPath,
+                                bool removeEnvironmentRPath, std::string* emsg,
                                 bool* changed)
 {
   if (changed) {
@@ -2484,7 +2455,9 @@
 
       // Construct the new value which preserves the part of the path
       // not being changed.
-      rp[rp_count].Value = se[i]->Value.substr(0, prefix_len);
+      if (!removeEnvironmentRPath) {
+        rp[rp_count].Value = se[i]->Value.substr(0, prefix_len);
+      }
       rp[rp_count].Value += newRPath;
       rp[rp_count].Value += se[i]->Value.substr(pos + oldRPath.length());
 
@@ -2570,6 +2543,7 @@
 bool cmSystemTools::ChangeRPath(std::string const& /*file*/,
                                 std::string const& /*oldRPath*/,
                                 std::string const& /*newRPath*/,
+                                bool /*removeEnvironmentRPath*/,
                                 std::string* /*emsg*/, bool* /*changed*/)
 {
   return false;
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index a9c03bd..1962389 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -8,6 +8,7 @@
 #include "cmCryptoHash.h"
 #include "cmDuration.h"
 #include "cmProcessOutput.h"
+#include "cm_string_view.hxx"
 #include "cmsys/Process.h"
 #include "cmsys/SystemTools.hxx" // IWYU pragma: export
 #include <functional>
@@ -149,26 +150,45 @@
    * forced this value. This is not the same as On, but this
    * may be considered as "internally switched on".
    */
-  static bool IsInternallyOn(const char* val);
-  /**
-   * does a string indicate a true or on value ? This is not the same
-   * as ifdef.
-   */
-  static bool IsOn(const char* val);
-  static bool IsOn(const std::string& val);
+  static bool IsInternallyOn(cm::string_view val);
+  static inline bool IsInternallyOn(const char* val)
+  {
+    if (!val) {
+      return false;
+    }
+    return IsInternallyOn(cm::string_view(val));
+  }
 
   /**
-   * does a string indicate a false or off value ? Note that this is
+   * Does a string indicate a true or on value? This is not the same as ifdef.
+   */
+  static bool IsOn(cm::string_view val);
+  inline static bool IsOn(const char* val)
+  {
+    if (!val) {
+      return false;
+    }
+    return IsOn(cm::string_view(val));
+  }
+
+  /**
+   * Does a string indicate a false or off value ? Note that this is
    * not the same as !IsOn(...) because there are a number of
    * ambiguous values such as "/usr/local/bin" a path will result in
    * IsON and IsOff both returning false. Note that the special path
    * NOTFOUND, *-NOTFOUND or IGNORE will cause IsOff to return true.
    */
-  static bool IsOff(const char* val);
-  static bool IsOff(const std::string& val);
+  static bool IsOff(cm::string_view val);
+  inline static bool IsOff(const char* val)
+  {
+    if (!val) {
+      return true;
+    }
+    return IsOff(cm::string_view(val));
+  }
 
   //! Return true if value is NOTFOUND or ends in -NOTFOUND.
-  static bool IsNOTFOUND(const char* value);
+  static bool IsNOTFOUND(cm::string_view val);
   //! Return true if the path is a framework
   static bool IsPathToFramework(const std::string& value);
 
@@ -473,6 +493,7 @@
   /** Try to set the RPATH in an ELF binary.  */
   static bool ChangeRPath(std::string const& file, std::string const& oldRPath,
                           std::string const& newRPath,
+                          bool removeEnvironmentRPath,
                           std::string* emsg = nullptr,
                           bool* changed = nullptr);
 
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index b10b30f..beccfce 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -12,6 +12,8 @@
 #include <string.h>
 #include <unordered_set>
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmCustomCommand.h"
 #include "cmGeneratorExpression.h"
@@ -168,7 +170,8 @@
   cmPropertyMap Properties;
   bool IsGeneratorProvided;
   bool HaveInstallRule;
-  bool DLLPlatform;
+  bool IsDLLPlatform;
+  bool IsAIX;
   bool IsAndroid;
   bool IsImportedTarget;
   bool ImportedGloballyVisible;
@@ -216,7 +219,8 @@
   impl->Name = name;
   impl->IsGeneratorProvided = false;
   impl->HaveInstallRule = false;
-  impl->DLLPlatform = false;
+  impl->IsDLLPlatform = false;
+  impl->IsAIX = false;
   impl->IsAndroid = false;
   impl->IsImportedTarget =
     (vis == VisibilityImported || vis == VisibilityImportedGlobally);
@@ -224,9 +228,13 @@
   impl->BuildInterfaceIncludesAppended = false;
 
   // Check whether this is a DLL platform.
-  impl->DLLPlatform =
+  impl->IsDLLPlatform =
     !impl->Makefile->GetSafeDefinition("CMAKE_IMPORT_LIBRARY_SUFFIX").empty();
 
+  // Check whether we are targeting AIX.
+  impl->IsAIX =
+    (impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "AIX");
+
   // Check whether we are targeting an Android platform.
   impl->IsAndroid =
     (impl->Makefile->GetSafeDefinition("CMAKE_SYSTEM_NAME") == "Android");
@@ -274,6 +282,7 @@
     initProp("BUILD_RPATH");
     initProp("BUILD_RPATH_USE_ORIGIN");
     initProp("INSTALL_NAME_DIR");
+    initProp("INSTALL_REMOVE_ENVIRONMENT_RPATH");
     initPropValue("INSTALL_RPATH", "");
     initPropValue("INSTALL_RPATH_USE_LINK_PATH", "OFF");
     initProp("INTERPROCEDURAL_OPTIMIZATION");
@@ -1657,6 +1666,16 @@
   return impl->Properties;
 }
 
+bool cmTarget::IsDLLPlatform() const
+{
+  return impl->IsDLLPlatform;
+}
+
+bool cmTarget::IsAIX() const
+{
+  return impl->IsAIX;
+}
+
 bool cmTarget::IsImported() const
 {
   return impl->IsImportedTarget;
@@ -1698,7 +1717,8 @@
                     ? "CMAKE_SHARED_LIBRARY_SUFFIX"
                     : "CMAKE_EXECUTABLE_SUFFIX");
         case cmStateEnums::ImportLibraryArtifact:
-          return "CMAKE_IMPORT_LIBRARY_SUFFIX";
+          return (impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_SUFFIX"
+                              : "CMAKE_IMPORT_LIBRARY_SUFFIX");
       }
       break;
     default:
@@ -1738,7 +1758,8 @@
                     ? "CMAKE_SHARED_LIBRARY_PREFIX"
                     : "");
         case cmStateEnums::ImportLibraryArtifact:
-          return "CMAKE_IMPORT_LIBRARY_PREFIX";
+          return (impl->IsAIX ? "CMAKE_AIX_IMPORT_FILE_PREFIX"
+                              : "CMAKE_IMPORT_LIBRARY_PREFIX");
       }
       break;
     default:
@@ -1872,9 +1893,10 @@
   // If we needed to find one of the mapped configurations but did not
   // On a DLL platform there may be only IMPORTED_IMPLIB for a shared
   // library or an executable with exports.
-  bool allowImp = (impl->DLLPlatform &&
+  bool allowImp = (this->IsDLLPlatform() &&
                    (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
-                    this->IsExecutableWithExports()));
+                    this->IsExecutableWithExports())) ||
+    (this->IsAIX() && this->IsExecutableWithExports());
 
   // If a mapping was found, check its configurations.
   for (std::vector<std::string>::const_iterator mci = mappedConfigs.begin();
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index f47cc14..a808bb4 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -177,6 +177,12 @@
   //! Get all properties
   cmPropertyMap const& GetProperties() const;
 
+  //! Return whether or not the target is for a DLL platform.
+  bool IsDLLPlatform() const;
+
+  //! Return whether or not we are targeting AIX.
+  bool IsAIX() const;
+
   bool IsImported() const;
   bool IsImportedGloballyVisible() const;
 
diff --git a/Source/cmTargetCompileDefinitionsCommand.h b/Source/cmTargetCompileDefinitionsCommand.h
index d41483a..25af21d 100644
--- a/Source/cmTargetCompileDefinitionsCommand.h
+++ b/Source/cmTargetCompileDefinitionsCommand.h
@@ -8,9 +8,11 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
 #include "cmTargetPropCommandBase.h"
 
-class cmCommand;
 class cmExecutionStatus;
 class cmTarget;
 
@@ -20,7 +22,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmTargetCompileDefinitionsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmTargetCompileDefinitionsCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmTargetCompileFeaturesCommand.h b/Source/cmTargetCompileFeaturesCommand.h
index 45240a5..07948fa 100644
--- a/Source/cmTargetCompileFeaturesCommand.h
+++ b/Source/cmTargetCompileFeaturesCommand.h
@@ -8,15 +8,20 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
 #include "cmTargetPropCommandBase.h"
 
-class cmCommand;
 class cmExecutionStatus;
 class cmTarget;
 
 class cmTargetCompileFeaturesCommand : public cmTargetPropCommandBase
 {
-  cmCommand* Clone() override { return new cmTargetCompileFeaturesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmTargetCompileFeaturesCommand>();
+  }
 
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
diff --git a/Source/cmTargetCompileOptionsCommand.h b/Source/cmTargetCompileOptionsCommand.h
index 6fb151a..a571cfb 100644
--- a/Source/cmTargetCompileOptionsCommand.h
+++ b/Source/cmTargetCompileOptionsCommand.h
@@ -8,9 +8,11 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
 #include "cmTargetPropCommandBase.h"
 
-class cmCommand;
 class cmExecutionStatus;
 class cmTarget;
 
@@ -20,7 +22,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmTargetCompileOptionsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmTargetCompileOptionsCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmTargetIncludeDirectoriesCommand.h b/Source/cmTargetIncludeDirectoriesCommand.h
index 57bf8fc..6defab2 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.h
+++ b/Source/cmTargetIncludeDirectoriesCommand.h
@@ -8,9 +8,11 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
 #include "cmTargetPropCommandBase.h"
 
-class cmCommand;
 class cmExecutionStatus;
 class cmTarget;
 
@@ -20,7 +22,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmTargetIncludeDirectoriesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmTargetIncludeDirectoriesCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmTargetLinkDirectoriesCommand.h b/Source/cmTargetLinkDirectoriesCommand.h
index 52c75a0..a2fcfa9 100644
--- a/Source/cmTargetLinkDirectoriesCommand.h
+++ b/Source/cmTargetLinkDirectoriesCommand.h
@@ -8,9 +8,11 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
 #include "cmTargetPropCommandBase.h"
 
-class cmCommand;
 class cmExecutionStatus;
 class cmTarget;
 
@@ -20,7 +22,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmTargetLinkDirectoriesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmTargetLinkDirectoriesCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmTargetLinkLibrariesCommand.h b/Source/cmTargetLinkLibrariesCommand.h
index 54f8cf4..6698ce0 100644
--- a/Source/cmTargetLinkLibrariesCommand.h
+++ b/Source/cmTargetLinkLibrariesCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 #include "cmTargetLinkLibraryType.h"
 
@@ -30,7 +32,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmTargetLinkLibrariesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmTargetLinkLibrariesCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmTargetLinkOptionsCommand.h b/Source/cmTargetLinkOptionsCommand.h
index a1fc9fc..3710739 100644
--- a/Source/cmTargetLinkOptionsCommand.h
+++ b/Source/cmTargetLinkOptionsCommand.h
@@ -8,9 +8,11 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
 #include "cmTargetPropCommandBase.h"
 
-class cmCommand;
 class cmExecutionStatus;
 class cmTarget;
 
@@ -20,7 +22,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmTargetLinkOptionsCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmTargetLinkOptionsCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index 1b8ee81..3aa845c 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -32,12 +32,13 @@
     this->HandleMissingTarget(args[0]);
     return false;
   }
-  if ((this->Target->GetType() != cmStateEnums::SHARED_LIBRARY) &&
+  if ((this->Target->GetType() != cmStateEnums::EXECUTABLE) &&
       (this->Target->GetType() != cmStateEnums::STATIC_LIBRARY) &&
-      (this->Target->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
+      (this->Target->GetType() != cmStateEnums::SHARED_LIBRARY) &&
       (this->Target->GetType() != cmStateEnums::MODULE_LIBRARY) &&
+      (this->Target->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
       (this->Target->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
-      (this->Target->GetType() != cmStateEnums::EXECUTABLE)) {
+      (this->Target->GetType() != cmStateEnums::UNKNOWN_LIBRARY)) {
     this->SetError("called with non-compilable target type");
     return false;
   }
diff --git a/Source/cmTargetSourcesCommand.h b/Source/cmTargetSourcesCommand.h
index b01e3ca..90fd45f 100644
--- a/Source/cmTargetSourcesCommand.h
+++ b/Source/cmTargetSourcesCommand.h
@@ -8,9 +8,11 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
 #include "cmTargetPropCommandBase.h"
 
-class cmCommand;
 class cmExecutionStatus;
 class cmTarget;
 
@@ -20,7 +22,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmTargetSourcesCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmTargetSourcesCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h
index 8237878..ec9f8b8 100644
--- a/Source/cmTryCompileCommand.h
+++ b/Source/cmTryCompileCommand.h
@@ -8,9 +8,11 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
 #include "cmCoreTryCompile.h"
 
-class cmCommand;
 class cmExecutionStatus;
 
 /** \class cmTryCompileCommand
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmTryCompileCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmTryCompileCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index a92c2a0..ed944ac 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -137,7 +137,7 @@
       // now put the output into the variables
       if (!this->RunOutputVariable.empty()) {
         this->Makefile->AddDefinition(this->RunOutputVariable,
-                                      runOutputContents.c_str());
+                                      runOutputContents);
       }
 
       if (!this->OutputVariable.empty()) {
@@ -148,8 +148,7 @@
         if (compileOutput) {
           runOutputContents = compileOutput + runOutputContents;
         }
-        this->Makefile->AddDefinition(this->OutputVariable,
-                                      runOutputContents.c_str());
+        this->Makefile->AddDefinition(this->OutputVariable, runOutputContents);
       }
     }
   }
diff --git a/Source/cmTryRunCommand.h b/Source/cmTryRunCommand.h
index c54622c..bacfcdb 100644
--- a/Source/cmTryRunCommand.h
+++ b/Source/cmTryRunCommand.h
@@ -8,9 +8,11 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
+#include "cmCommand.h"
 #include "cmCoreTryCompile.h"
 
-class cmCommand;
 class cmExecutionStatus;
 
 /** \class cmTryRunCommand
@@ -24,7 +26,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmTryRunCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmTryRunCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmUVProcessChain.cxx b/Source/cmUVProcessChain.cxx
index 90ece0b..56d6c09 100644
--- a/Source/cmUVProcessChain.cxx
+++ b/Source/cmUVProcessChain.cxx
@@ -2,7 +2,6 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmUVProcessChain.h"
 
-#include "cmAlgorithms.h"
 #include "cmGetPipes.h"
 #include "cmUVHandlePtr.h"
 #include "cmUVStreambuf.h"
@@ -10,10 +9,12 @@
 
 #include <assert.h>
 
+#include <istream> // IWYU pragma: keep
 #include <iterator>
-#include <memory>
 #include <utility>
 
+#include "cm_memory.hxx"
+
 struct cmUVProcessChain::InternalData
 {
   struct BasicStreamData
diff --git a/Source/cmUnexpectedCommand.cxx b/Source/cmUnexpectedCommand.cxx
deleted file mode 100644
index a8de9e6..0000000
--- a/Source/cmUnexpectedCommand.cxx
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#include "cmUnexpectedCommand.h"
-
-#include <stdlib.h>
-
-#include "cmMakefile.h"
-
-class cmExecutionStatus;
-
-bool cmUnexpectedCommand::InitialPass(std::vector<std::string> const&,
-                                      cmExecutionStatus&)
-{
-  const char* versionValue =
-    this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION");
-  if (this->Name == "endif" && (!versionValue || atof(versionValue) <= 1.4)) {
-    return true;
-  }
-
-  this->SetError(this->Error);
-  return false;
-}
diff --git a/Source/cmUnexpectedCommand.h b/Source/cmUnexpectedCommand.h
deleted file mode 100644
index 33d6bdc..0000000
--- a/Source/cmUnexpectedCommand.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file Copyright.txt or https://cmake.org/licensing for details.  */
-#ifndef cmUnexpectedCommand_h
-#define cmUnexpectedCommand_h
-
-#include "cmConfigure.h" // IWYU pragma: keep
-
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "cmCommand.h"
-
-class cmExecutionStatus;
-
-class cmUnexpectedCommand : public cmCommand
-{
-public:
-  cmUnexpectedCommand(std::string name, const char* error)
-    : Name(std::move(name))
-    , Error(error)
-  {
-  }
-
-  cmCommand* Clone() override
-  {
-    return new cmUnexpectedCommand(this->Name, this->Error);
-  }
-
-  bool InitialPass(std::vector<std::string> const& args,
-                   cmExecutionStatus& status) override;
-
-private:
-  std::string Name;
-  const char* Error;
-};
-
-#endif
diff --git a/Source/cmUnsetCommand.h b/Source/cmUnsetCommand.h
index 4e1208a..9b78d44 100644
--- a/Source/cmUnsetCommand.h
+++ b/Source/cmUnsetCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,7 +25,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmUnsetCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmUnsetCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cmUseMangledMesaCommand.h b/Source/cmUseMangledMesaCommand.h
index e2f1d9b..1c01596 100644
--- a/Source/cmUseMangledMesaCommand.h
+++ b/Source/cmUseMangledMesaCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,7 +17,10 @@
 class cmUseMangledMesaCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmUseMangledMesaCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmUseMangledMesaCommand>();
+  }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
 
diff --git a/Source/cmUtilitySourceCommand.h b/Source/cmUtilitySourceCommand.h
index 165ecef..cef7fed 100644
--- a/Source/cmUtilitySourceCommand.h
+++ b/Source/cmUtilitySourceCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,7 +17,10 @@
 class cmUtilitySourceCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmUtilitySourceCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmUtilitySourceCommand>();
+  }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
 };
diff --git a/Source/cmVariableRequiresCommand.cxx b/Source/cmVariableRequiresCommand.cxx
index c02157a..9878ff1 100644
--- a/Source/cmVariableRequiresCommand.cxx
+++ b/Source/cmVariableRequiresCommand.cxx
@@ -42,7 +42,7 @@
   // if reqVar is set to true, but requirementsMet is false , then
   // set reqVar to false.
   if (!reqVar || (!requirementsMet && this->Makefile->IsOn(reqVar))) {
-    this->Makefile->AddDefinition(resultVariable, requirementsMet);
+    this->Makefile->AddDefinitionBool(resultVariable, requirementsMet);
   }
 
   if (!requirementsMet) {
diff --git a/Source/cmVariableRequiresCommand.h b/Source/cmVariableRequiresCommand.h
index 94970c5..38e7490 100644
--- a/Source/cmVariableRequiresCommand.h
+++ b/Source/cmVariableRequiresCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -15,7 +17,10 @@
 class cmVariableRequiresCommand : public cmCommand
 {
 public:
-  cmCommand* Clone() override { return new cmVariableRequiresCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmVariableRequiresCommand>();
+  }
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
 };
diff --git a/Source/cmVariableWatchCommand.cxx b/Source/cmVariableWatchCommand.cxx
index 5fe55bd..83a774d 100644
--- a/Source/cmVariableWatchCommand.cxx
+++ b/Source/cmVariableWatchCommand.cxx
@@ -3,6 +3,7 @@
 #include "cmVariableWatchCommand.h"
 
 #include <sstream>
+#include <utility>
 
 #include "cmExecutionStatus.h"
 #include "cmListFileCache.h"
@@ -54,7 +55,7 @@
     newLFF.Arguments.emplace_back(stack, cmListFileArgument::Quoted, 9999);
     newLFF.Name = data->Command;
     newLFF.Line = 9999;
-    cmExecutionStatus status;
+    cmExecutionStatus status(*makefile);
     if (!makefile->ExecuteCommand(newLFF, status)) {
       std::ostringstream error;
       error << "Error in cmake code at\nUnknown:0:\n"
@@ -84,15 +85,39 @@
   delete data;
 }
 
-cmVariableWatchCommand::cmVariableWatchCommand() = default;
-
-cmVariableWatchCommand::~cmVariableWatchCommand()
+/** This command does not really have a final pass but it needs to
+    stay alive since it owns variable watch callback information. */
+class FinalAction
 {
-  for (std::string const& wv : this->WatchedVariables) {
-    this->Makefile->GetCMakeInstance()->GetVariableWatch()->RemoveWatch(
-      wv, cmVariableWatchCommandVariableAccessed);
+public:
+  FinalAction(cmMakefile* makefile, std::string variable)
+    : Action(std::make_shared<Impl>(makefile, std::move(variable)))
+  {
   }
-}
+
+  void operator()(cmMakefile&) const {}
+
+private:
+  struct Impl
+  {
+    Impl(cmMakefile* makefile, std::string variable)
+      : Makefile(makefile)
+      , Variable(std::move(variable))
+    {
+    }
+
+    ~Impl()
+    {
+      this->Makefile->GetCMakeInstance()->GetVariableWatch()->RemoveWatch(
+        this->Variable, cmVariableWatchCommandVariableAccessed);
+    }
+
+    cmMakefile* Makefile;
+    std::string Variable;
+  };
+
+  std::shared_ptr<Impl const> Action;
+};
 
 bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args,
                                          cmExecutionStatus&)
@@ -118,7 +143,6 @@
   data->InCallback = false;
   data->Command = command;
 
-  this->WatchedVariables.insert(variable);
   if (!this->Makefile->GetCMakeInstance()->GetVariableWatch()->AddWatch(
         variable, cmVariableWatchCommandVariableAccessed, data,
         deleteVariableWatchCallbackData)) {
@@ -126,5 +150,6 @@
     return false;
   }
 
+  this->Makefile->AddFinalAction(FinalAction(this->Makefile, variable));
   return true;
 }
diff --git a/Source/cmVariableWatchCommand.h b/Source/cmVariableWatchCommand.h
index 6a8115d..221269f 100644
--- a/Source/cmVariableWatchCommand.h
+++ b/Source/cmVariableWatchCommand.h
@@ -5,10 +5,11 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include <set>
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -23,13 +24,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmVariableWatchCommand; }
-
-  //! Default constructor
-  cmVariableWatchCommand();
-
-  //! Destructor.
-  ~cmVariableWatchCommand() override;
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmVariableWatchCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
@@ -37,13 +35,6 @@
    */
   bool InitialPass(std::vector<std::string> const& args,
                    cmExecutionStatus& status) override;
-
-  /** This command does not really have a final pass but it needs to
-      stay alive since it owns variable watch callback information. */
-  bool HasFinalPass() const override { return true; }
-
-protected:
-  std::set<std::string> WatchedVariables;
 };
 
 #endif
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index d17a6d8..4a151b3 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -19,9 +19,10 @@
 #include "windows.h"
 
 #include <iterator>
-#include <memory>
 #include <set>
 
+#include "cm_memory.hxx"
+
 static void ConvertToWindowsSlash(std::string& s);
 
 static std::string cmVS10EscapeXML(std::string arg)
@@ -1218,7 +1219,7 @@
       this->GeneratorTarget->GetPropertyAsBool("VS_WINRT_EXTENSIONS")) {
     e1.Element("CharacterSet", "Unicode");
   } else if (this->GeneratorTarget->GetType() <=
-               cmStateEnums::MODULE_LIBRARY &&
+               cmStateEnums::OBJECT_LIBRARY &&
              this->ClOptions[config]->UsingSBCS()) {
     e1.Element("CharacterSet", "NotSet");
   } else {
@@ -2648,8 +2649,7 @@
         clOptions.AddFlag("UseFullPaths", "false");
       }
       clOptions.AddFlag("PrecompiledHeader", "NotUsing");
-      std::string asmLocation = configName + "/";
-      clOptions.AddFlag("AssemblerListingLocation", asmLocation);
+      clOptions.AddFlag("AssemblerListingLocation", "$(IntDir)");
     }
   }
 
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index 0d3bdf8..37d1c74 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -2,6 +2,8 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmWhileCommand.h"
 
+#include "cm_memory.hxx"
+
 #include "cmConditionEvaluator.h"
 #include "cmExecutionStatus.h"
 #include "cmExpandedCommandArgument.h"
@@ -9,7 +11,8 @@
 #include "cmMessageType.h"
 #include "cmSystemTools.h"
 
-#include <memory>
+#include <string>
+#include <utility>
 
 cmWhileFunctionBlocker::cmWhileFunctionBlocker(cmMakefile* mf)
   : Makefile(mf)
@@ -80,7 +83,7 @@
 
         // Invoke all the functions that were collected in the block.
         for (cmListFileFunction const& fn : this->Functions) {
-          cmExecutionStatus status;
+          cmExecutionStatus status(mf);
           mf.ExecuteCommand(fn, status);
           if (status.GetReturnInvoked()) {
             inStatus.SetReturnInvoked();
@@ -127,18 +130,20 @@
   return false;
 }
 
-bool cmWhileCommand::InvokeInitialPass(
-  const std::vector<cmListFileArgument>& args, cmExecutionStatus&)
+bool cmWhileCommand(std::vector<cmListFileArgument> const& args,
+                    cmExecutionStatus& status)
 {
   if (args.empty()) {
-    this->SetError("called with incorrect number of arguments");
+    status.SetError("called with incorrect number of arguments");
     return false;
   }
 
   // create a function blocker
-  cmWhileFunctionBlocker* f = new cmWhileFunctionBlocker(this->Makefile);
-  f->Args = args;
-  this->Makefile->AddFunctionBlocker(f);
-
+  {
+    cmMakefile& makefile = status.GetMakefile();
+    auto fb = cm::make_unique<cmWhileFunctionBlocker>(&makefile);
+    fb->Args = args;
+    makefile.AddFunctionBlocker(std::move(fb));
+  }
   return true;
 }
diff --git a/Source/cmWhileCommand.h b/Source/cmWhileCommand.h
index 6f6d405..2257799 100644
--- a/Source/cmWhileCommand.h
+++ b/Source/cmWhileCommand.h
@@ -5,10 +5,8 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include <string>
 #include <vector>
 
-#include "cmCommand.h"
 #include "cmFunctionBlocker.h"
 #include "cmListFileCache.h"
 
@@ -33,30 +31,7 @@
 };
 
 /// \brief Starts a while loop
-class cmWhileCommand : public cmCommand
-{
-public:
-  /**
-   * This is a virtual constructor for the command.
-   */
-  cmCommand* Clone() override { return new cmWhileCommand; }
-
-  /**
-   * This overrides the default InvokeInitialPass implementation.
-   * It records the arguments before expansion.
-   */
-  bool InvokeInitialPass(const std::vector<cmListFileArgument>& args,
-                         cmExecutionStatus&) override;
-
-  /**
-   * This is called when the command is first encountered in
-   * the CMakeLists.txt file.
-   */
-  bool InitialPass(std::vector<std::string> const&,
-                   cmExecutionStatus&) override
-  {
-    return false;
-  }
-};
+bool cmWhileCommand(std::vector<cmListFileArgument> const& args,
+                    cmExecutionStatus& status);
 
 #endif
diff --git a/Source/cmWorkerPool.cxx b/Source/cmWorkerPool.cxx
index cbf070e..974100b 100644
--- a/Source/cmWorkerPool.cxx
+++ b/Source/cmWorkerPool.cxx
@@ -16,6 +16,8 @@
 #include <stddef.h>
 #include <thread>
 
+#include "cm_memory.hxx"
+
 /**
  * @brief libuv pipe buffer class
  */
diff --git a/Source/cmWorkerPool.h b/Source/cmWorkerPool.h
index 5cc308b..d708118 100644
--- a/Source/cmWorkerPool.h
+++ b/Source/cmWorkerPool.h
@@ -5,14 +5,13 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
-#include "cmAlgorithms.h" // IWYU pragma: keep
-
-#include <memory>
 #include <stdint.h>
 #include <string>
 #include <utility>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 // -- Types
 class cmWorkerPoolInternal;
 
diff --git a/Source/cmWriteFileCommand.h b/Source/cmWriteFileCommand.h
index 9028f84..3961898 100644
--- a/Source/cmWriteFileCommand.h
+++ b/Source/cmWriteFileCommand.h
@@ -8,6 +8,8 @@
 #include <string>
 #include <vector>
 
+#include "cm_memory.hxx"
+
 #include "cmCommand.h"
 
 class cmExecutionStatus;
@@ -22,7 +24,10 @@
   /**
    * This is a virtual constructor for the command.
    */
-  cmCommand* Clone() override { return new cmWriteFileCommand; }
+  std::unique_ptr<cmCommand> Clone() override
+  {
+    return cm::make_unique<cmWriteFileCommand>();
+  }
 
   /**
    * This is called when the command is first encountered in
diff --git a/Source/cm_memory.hxx b/Source/cm_memory.hxx
new file mode 100644
index 0000000..9f5e678
--- /dev/null
+++ b/Source/cm_memory.hxx
@@ -0,0 +1,31 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file Copyright.txt or https://cmake.org/licensing for details.  */
+#ifndef cm_memory_hxx
+#define cm_memory_hxx
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <memory> // IWYU pragma: export
+#if !defined(CMake_HAVE_CXX_MAKE_UNIQUE)
+#  include <utility>
+#endif
+
+namespace cm {
+
+#if defined(CMake_HAVE_CXX_MAKE_UNIQUE)
+
+using std::make_unique;
+
+#else
+
+template <typename T, typename... Args>
+std::unique_ptr<T> make_unique(Args&&... args)
+{
+  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+#endif
+
+} // namespace cm
+
+#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index b8238a2..7250e51 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -2,6 +2,8 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmake.h"
 
+#include "cm_memory.hxx"
+
 #include "cmAlgorithms.h"
 #include "cmCommands.h"
 #include "cmDocumentation.h"
@@ -104,7 +106,6 @@
 #include <cstring>
 #include <initializer_list>
 #include <iostream>
-#include <memory>
 #include <sstream>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index a6348b3..cfb3cee 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -31,13 +31,14 @@
 #include <string>
 #include <vector>
 
+namespace {
 #ifdef CMAKE_BUILD_WITH_CMAKE
-static const char* cmDocumentationName[][2] = {
+const char* cmDocumentationName[][2] = {
   { nullptr, "  cmake - Cross-Platform Makefile Generator." },
   { nullptr, nullptr }
 };
 
-static const char* cmDocumentationUsage[][2] = {
+const char* cmDocumentationUsage[][2] = {
   { nullptr,
     "  cmake [options] <path-to-source>\n"
     "  cmake [options] <path-to-existing-build>\n"
@@ -49,40 +50,12 @@
   { nullptr, nullptr }
 };
 
-static const char* cmDocumentationUsageNote[][2] = {
+const char* cmDocumentationUsageNote[][2] = {
   { nullptr, "Run 'cmake --help' for more information." },
   { nullptr, nullptr }
 };
 
-#  define CMAKE_BUILD_OPTIONS                                                 \
-    "  <dir>          = Project binary directory to be built.\n"              \
-    "  --parallel [<jobs>], -j [<jobs>]\n"                                    \
-    "                 = Build in parallel using the given number of jobs. \n" \
-    "                   If <jobs> is omitted the native build tool's \n"      \
-    "                   default number is used.\n"                            \
-    "                   The CMAKE_BUILD_PARALLEL_LEVEL environment "          \
-    "variable\n"                                                              \
-    "                   specifies a default parallel level when this "        \
-    "option\n"                                                                \
-    "                   is not given.\n"                                      \
-    "  --target <tgt>..., -t <tgt>... \n"                                     \
-    "                 = Build <tgt> instead of default targets.\n"            \
-    "  --config <cfg> = For multi-configuration tools, choose <cfg>.\n"       \
-    "  --clean-first  = Build target 'clean' first, then build.\n"            \
-    "                   (To clean only, use --target 'clean'.)\n"             \
-    "  --verbose, -v  = Enable verbose output - if supported - including\n"   \
-    "                   the build commands to be executed. \n"                \
-    "  --             = Pass remaining options to the native tool.\n"
-
-#  define CMAKE_INSTALL_OPTIONS                                               \
-    "  <dir>              = Project binary directory to install.\n"           \
-    "  --config <cfg>     = For multi-configuration tools, choose <cfg>.\n"   \
-    "  --component <comp> = Component-based install. Only install <comp>.\n"  \
-    "  --prefix <prefix>  = The installation prefix CMAKE_INSTALL_PREFIX.\n"  \
-    "  --strip            = Performing install/strip.\n"                      \
-    "  -v --verbose       = Enable verbose output.\n"
-
-static const char* cmDocumentationOptions[][2] = {
+const char* cmDocumentationOptions[][2] = {
   CMAKE_STANDARD_OPTIONS_TABLE,
   { "-E", "CMake command mode." },
   { "-L[A][H]", "List non-advanced cached variables." },
@@ -117,7 +90,7 @@
 
 #endif
 
-static int do_command(int ac, char const* const* av)
+int do_command(int ac, char const* const* av)
 {
   std::vector<std::string> args;
   args.reserve(ac - 1);
@@ -126,12 +99,7 @@
   return cmcmd::ExecuteCMakeCommand(args);
 }
 
-int do_cmake(int ac, char const* const* av);
-static int do_build(int ac, char const* const* av);
-static int do_install(int ac, char const* const* av);
-static int do_open(int ac, char const* const* av);
-
-static cmMakefile* cmakemainGetMakefile(cmake* cm)
+cmMakefile* cmakemainGetMakefile(cmake* cm)
 {
   if (cm && cm->GetDebugOutput()) {
     cmGlobalGenerator* gg = cm->GetGlobalGenerator();
@@ -142,7 +110,7 @@
   return nullptr;
 }
 
-static std::string cmakemainGetStack(cmake* cm)
+std::string cmakemainGetStack(cmake* cm)
 {
   std::string msg;
   cmMakefile* mf = cmakemainGetMakefile(cm);
@@ -156,14 +124,13 @@
   return msg;
 }
 
-static void cmakemainMessageCallback(const std::string& m,
-                                     const char* /*unused*/, cmake* cm)
+void cmakemainMessageCallback(const std::string& m, const char* /*unused*/,
+                              cmake* cm)
 {
-  std::cerr << m << cmakemainGetStack(cm) << std::endl << std::flush;
+  std::cerr << m << cmakemainGetStack(cm) << std::endl;
 }
 
-static void cmakemainProgressCallback(const std::string& m, float prog,
-                                      cmake* cm)
+void cmakemainProgressCallback(const std::string& m, float prog, cmake* cm)
 {
   cmMakefile* mf = cmakemainGetMakefile(cm);
   std::string dir;
@@ -178,48 +145,6 @@
   if ((prog < 0) || (!dir.empty())) {
     std::cout << "-- " << m << dir << cmakemainGetStack(cm) << std::endl;
   }
-
-  std::cout.flush();
-}
-
-int main(int ac, char const* const* av)
-{
-  cmSystemTools::EnsureStdPipes();
-#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
-  // Replace streambuf so we can output Unicode to console
-  cmsys::ConsoleBuf::Manager consoleOut(std::cout);
-  consoleOut.SetUTF8Pipes();
-  cmsys::ConsoleBuf::Manager consoleErr(std::cerr, true);
-  consoleErr.SetUTF8Pipes();
-#endif
-  cmsys::Encoding::CommandLineArguments args =
-    cmsys::Encoding::CommandLineArguments::Main(ac, av);
-  ac = args.argc();
-  av = args.argv();
-
-  cmSystemTools::EnableMSVCDebugHook();
-  cmSystemTools::InitializeLibUV();
-  cmSystemTools::FindCMakeResources(av[0]);
-  if (ac > 1) {
-    if (strcmp(av[1], "--build") == 0) {
-      return do_build(ac, av);
-    }
-    if (strcmp(av[1], "--install") == 0) {
-      return do_install(ac, av);
-    }
-    if (strcmp(av[1], "--open") == 0) {
-      return do_open(ac, av);
-    }
-    if (strcmp(av[1], "-E") == 0) {
-      return do_command(ac, av);
-    }
-  }
-  int ret = do_cmake(ac, av);
-#ifdef CMAKE_BUILD_WITH_CMAKE
-  cmDynamicLoader::FlushCache();
-#endif
-  uv_loop_close(uv_default_loop());
-  return ret;
 }
 
 int do_cmake(int ac, char const* const* av)
@@ -381,7 +306,6 @@
   return 0;
 }
 
-namespace {
 int extract_job_number(int& index, char const* current, char const* next,
                        int len_of_flag)
 {
@@ -411,9 +335,8 @@
   }
   return jobs;
 }
-}
 
-static int do_build(int ac, char const* const* av)
+int do_build(int ac, char const* const* av)
 {
 #ifndef CMAKE_BUILD_WITH_CMAKE
   std::cerr << "This cmake does not support --build\n";
@@ -541,7 +464,24 @@
     std::cerr <<
       "Usage: cmake --build <dir> [options] [-- [native-options]]\n"
       "Options:\n"
-      CMAKE_BUILD_OPTIONS
+      "  <dir>          = Project binary directory to be built.\n"
+      "  --parallel [<jobs>], -j [<jobs>]\n"
+      "                 = Build in parallel using the given number of jobs. \n"
+      "                   If <jobs> is omitted the native build tool's \n"
+      "                   default number is used.\n"
+      "                   The CMAKE_BUILD_PARALLEL_LEVEL environment "
+      "variable\n"
+      "                   specifies a default parallel level when this "
+      "option\n"
+      "                   is not given.\n"
+      "  --target <tgt>..., -t <tgt>... \n"
+      "                 = Build <tgt> instead of default targets.\n"
+      "  --config <cfg> = For multi-configuration tools, choose <cfg>.\n"
+      "  --clean-first  = Build target 'clean' first, then build.\n"
+      "                   (To clean only, use --target 'clean'.)\n"
+      "  --verbose, -v  = Enable verbose output - if supported - including\n"
+      "                   the build commands to be executed. \n"
+      "  --             = Pass remaining options to the native tool.\n"
       ;
     /* clang-format on */
     return 1;
@@ -560,7 +500,7 @@
 #endif
 }
 
-static int do_install(int ac, char const* const* av)
+int do_install(int ac, char const* const* av)
 {
 #ifndef CMAKE_BUILD_WITH_CMAKE
   std::cerr << "This cmake does not support --install\n";
@@ -627,8 +567,18 @@
   }
 
   if (dir.empty()) {
-    std::cerr << "Usage: cmake --install <dir> "
-                 "[options]\nOptions:\n" CMAKE_INSTALL_OPTIONS;
+    /* clang-format off */
+    std::cerr <<
+      "Usage: cmake --install <dir> [options]\n"
+      "Options:\n"
+      "  <dir>              = Project binary directory to install.\n"
+      "  --config <cfg>     = For multi-configuration tools, choose <cfg>.\n"
+      "  --component <comp> = Component-based install. Only install <comp>.\n"
+      "  --prefix <prefix>  = The installation prefix CMAKE_INSTALL_PREFIX.\n"
+      "  --strip            = Performing install/strip.\n"
+      "  -v --verbose       = Enable verbose output.\n"
+      ;
+    /* clang-format on */
     return 1;
   }
 
@@ -671,7 +621,7 @@
 #endif
 }
 
-static int do_open(int ac, char const* const* av)
+int do_open(int ac, char const* const* av)
 {
 #ifndef CMAKE_BUILD_WITH_CMAKE
   std::cerr << "This cmake does not support --open\n";
@@ -713,3 +663,44 @@
   return cm.Open(dir, false) ? 0 : 1;
 #endif
 }
+} // namespace
+
+int main(int ac, char const* const* av)
+{
+  cmSystemTools::EnsureStdPipes();
+#if defined(_WIN32) && defined(CMAKE_BUILD_WITH_CMAKE)
+  // Replace streambuf so we can output Unicode to console
+  cmsys::ConsoleBuf::Manager consoleOut(std::cout);
+  consoleOut.SetUTF8Pipes();
+  cmsys::ConsoleBuf::Manager consoleErr(std::cerr, true);
+  consoleErr.SetUTF8Pipes();
+#endif
+  cmsys::Encoding::CommandLineArguments args =
+    cmsys::Encoding::CommandLineArguments::Main(ac, av);
+  ac = args.argc();
+  av = args.argv();
+
+  cmSystemTools::EnableMSVCDebugHook();
+  cmSystemTools::InitializeLibUV();
+  cmSystemTools::FindCMakeResources(av[0]);
+  if (ac > 1) {
+    if (strcmp(av[1], "--build") == 0) {
+      return do_build(ac, av);
+    }
+    if (strcmp(av[1], "--install") == 0) {
+      return do_install(ac, av);
+    }
+    if (strcmp(av[1], "--open") == 0) {
+      return do_open(ac, av);
+    }
+    if (strcmp(av[1], "-E") == 0) {
+      return do_command(ac, av);
+    }
+  }
+  int ret = do_cmake(ac, av);
+#ifdef CMAKE_BUILD_WITH_CMAKE
+  cmDynamicLoader::FlushCache();
+#endif
+  uv_loop_close(uv_default_loop());
+  return ret;
+}
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index effc094..503dce1 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -114,6 +114,8 @@
     << "  touch <file>...           - touch a <file>.\n"
     << "  touch_nocreate <file>...  - touch a <file> but do not create it.\n"
     << "  create_symlink old new    - create a symbolic link new -> old\n"
+    << "  true                      - do nothing with an exit code of 0\n"
+    << "  false                     - do nothing with an exit code of 1\n"
 #if defined(_WIN32) && !defined(__CYGWIN__)
     << "Available on Windows only:\n"
     << "  delete_regv key           - delete registry value\n"
@@ -891,6 +893,16 @@
       return 0;
     }
 
+    // Command to do nothing with an exit code of 0.
+    if (args[1] == "true") {
+      return 0;
+    }
+
+    // Command to do nothing with an exit code of 1.
+    if (args[1] == "false") {
+      return 1;
+    }
+
     // Internal CMake shared library support.
     if (args[1] == "cmake_symlink_library" && args.size() == 5) {
       return cmcmd::SymlinkLibrary(args);
diff --git a/Source/kwsys/CommandLineArguments.cxx b/Source/kwsys/CommandLineArguments.cxx
index a97f7a8..dc9f01d 100644
--- a/Source/kwsys/CommandLineArguments.cxx
+++ b/Source/kwsys/CommandLineArguments.cxx
@@ -67,10 +67,10 @@
 {
 public:
   CommandLineArgumentsInternal()
+    : UnknownArgumentCallback{ KWSYS_NULLPTR }
+    , ClientData{ KWSYS_NULLPTR }
+    , LastArgument{ 0 }
   {
-    this->UnknownArgumentCallback = KWSYS_NULLPTR;
-    this->ClientData = KWSYS_NULLPTR;
-    this->LastArgument = 0;
   }
 
   typedef CommandLineArgumentsVectorOfStrings VectorOfStrings;
diff --git a/Source/kwsys/RegularExpression.cxx b/Source/kwsys/RegularExpression.cxx
index 5f84b19..3e10765 100644
--- a/Source/kwsys/RegularExpression.cxx
+++ b/Source/kwsys/RegularExpression.cxx
@@ -337,7 +337,6 @@
 {
   const char* scan;
   const char* longest;
-  size_t len;
   int flags;
 
   if (exp == KWSYS_NULLPTR) {
@@ -412,7 +411,7 @@
     //
     if (flags & SPSTART) {
       longest = KWSYS_NULLPTR;
-      len = 0;
+      size_t len = 0;
       for (; scan != KWSYS_NULLPTR; scan = regnext(scan))
         if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
           longest = OPERAND(scan);
diff --git a/Source/kwsys/RegularExpression.hxx.in b/Source/kwsys/RegularExpression.hxx.in
index b7b93f9..ed86418 100644
--- a/Source/kwsys/RegularExpression.hxx.in
+++ b/Source/kwsys/RegularExpression.hxx.in
@@ -407,8 +407,12 @@
  * Create an empty regular expression.
  */
 inline RegularExpression::RegularExpression()
+  : regstart{}
+  , reganch{}
+  , regmust{}
+  , program{ 0 }
+  , progsize{}
 {
-  this->program = 0;
 }
 
 /**
@@ -416,8 +420,12 @@
  * compiles s.
  */
 inline RegularExpression::RegularExpression(const char* s)
+  : regstart{}
+  , reganch{}
+  , regmust{}
+  , program{ 0 }
+  , progsize{}
 {
-  this->program = 0;
   if (s) {
     this->compile(s);
   }
@@ -428,8 +436,12 @@
  * compiles s.
  */
 inline RegularExpression::RegularExpression(const std::string& s)
+  : regstart{}
+  , reganch{}
+  , regmust{}
+  , program{ 0 }
+  , progsize{}
 {
-  this->program = 0;
   this->compile(s);
 }
 
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 2135913..36f24c7 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -3394,15 +3394,16 @@
   static const std::string cur = ".";
   for (std::vector<std::string>::const_iterator i = first; i != last; ++i) {
     if (*i == up) {
-      if (out_components.size() > 1) {
+      // Remove the previous component if possible.  Ignore ../ components
+      // that try to go above the root.  Keep ../ components if they are
+      // at the beginning of a relative path (base path is relative).
+      if (out_components.size() > 1 && out_components.back() != up) {
         out_components.resize(out_components.size() - 1);
+      } else if (!out_components.empty() && out_components[0].empty()) {
+        out_components.emplace_back(std::move(*i));
       }
     } else if (!i->empty() && *i != cur) {
-#if __cplusplus >= 201103L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201103L)
-      out_components.push_back(std::move(*i));
-#else
-      out_components.push_back(*i);
-#endif
+      out_components.emplace_back(std::move(*i));
     }
   }
 }
@@ -4738,7 +4739,7 @@
       // Test progressively shorter logical-to-physical mappings.
       std::string cwd_str = cwd;
       std::string pwd_path;
-      Realpath(pwd_str.c_str(), pwd_path);
+      Realpath(pwd_str, pwd_path);
       while (cwd_str == pwd_path && cwd_str != pwd_str) {
         // The current pair of paths is a working logical mapping.
         cwd_changed = cwd_str;
@@ -4748,7 +4749,7 @@
         // mapping still works.
         pwd_str = SystemTools::GetFilenamePath(pwd_str);
         cwd_str = SystemTools::GetFilenamePath(cwd_str);
-        Realpath(pwd_str.c_str(), pwd_path);
+        Realpath(pwd_str, pwd_path);
       }
 
       // Add the translation to keep the logical path name.
diff --git a/Source/kwsys/testSystemTools.cxx b/Source/kwsys/testSystemTools.cxx
index 9a40b53..ffa6a29 100644
--- a/Source/kwsys/testSystemTools.cxx
+++ b/Source/kwsys/testSystemTools.cxx
@@ -684,9 +684,10 @@
 }
 
 static bool CheckCollapsePath(const std::string& path,
-                              const std::string& expected)
+                              const std::string& expected,
+                              const char* base = nullptr)
 {
-  std::string result = kwsys::SystemTools::CollapseFullPath(path);
+  std::string result = kwsys::SystemTools::CollapseFullPath(path, base);
   if (!kwsys::SystemTools::ComparePath(expected, result)) {
     std::cerr << "CollapseFullPath(" << path << ")  yielded " << result
               << " instead of " << expected << std::endl;
@@ -710,6 +711,9 @@
   res &= CheckCollapsePath("C:/", "C:/");
   res &= CheckCollapsePath("C:/../", "C:/");
   res &= CheckCollapsePath("C:/../../", "C:/");
+  res &= CheckCollapsePath("../b", "../../b", "../");
+  res &= CheckCollapsePath("../a/../b", "../b", "../rel");
+  res &= CheckCollapsePath("a/../b", "../rel/b", "../rel");
   return res;
 }
 
diff --git a/Tests/AliasTarget/CMakeLists.txt b/Tests/AliasTarget/CMakeLists.txt
index 6271988..fc70135 100644
--- a/Tests/AliasTarget/CMakeLists.txt
+++ b/Tests/AliasTarget/CMakeLists.txt
@@ -7,7 +7,7 @@
 # Clang/C2 in C++98 mode cannot properly handle some of MSVC headers
 if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
     CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
-  set(CMAKE_CXX_STANDARD 14)
+  set(CMAKE_CXX_STANDARD 11)
 endif()
 
 add_library(foo SHARED empty.cpp)
diff --git a/Tests/CMakeLib/testUVProcessChain.cxx b/Tests/CMakeLib/testUVProcessChain.cxx
index e926350..63c9943 100644
--- a/Tests/CMakeLib/testUVProcessChain.cxx
+++ b/Tests/CMakeLib/testUVProcessChain.cxx
@@ -1,6 +1,5 @@
 #include "cmUVProcessChain.h"
 
-#include "cmAlgorithms.h"
 #include "cmGetPipes.h"
 #include "cmUVHandlePtr.h"
 #include "cmUVStreambuf.h"
@@ -10,13 +9,14 @@
 #include <algorithm>
 #include <functional>
 #include <iostream>
-#include <memory>
 #include <sstream>
 #include <string>
 #include <vector>
 
 #include <csignal>
 
+#include "cm_memory.hxx"
+
 struct ExpectedStatus
 {
   bool Finished;
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index d951316..5b8f255 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -14,8 +14,8 @@
     ${build_generator_args}
     --build-project ${proj}
     ${${NAME}_CTEST_OPTIONS}
-    --build-options ${build_options}
-    ${${NAME}_BUILD_OPTIONS}
+    --build-options
+      ${${NAME}_BUILD_OPTIONS}
     ${_test_command})
   unset(_test_command)
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${dir}")
@@ -127,9 +127,10 @@
       )
   endif()
 
-  set(build_options)
   if(CMake_TEST_EXPLICIT_MAKE_PROGRAM)
-    list(APPEND build_options -DCMAKE_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM})
+    list(APPEND build_generator_args
+      --build-makeprogram ${CMake_TEST_EXPLICIT_MAKE_PROGRAM}
+      )
   endif()
 
   # Look for rpmbuild to use for tests.
@@ -528,7 +529,6 @@
       "${CMake_BINARY_DIR}/Tests/BundleUtilities"
       ${build_generator_args}
       --build-project BundleUtilities
-      --build-options ${build_options}
       )
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleUtilities")
 
@@ -541,9 +541,9 @@
         "${CMake_BINARY_DIR}/Tests/Qt4Deploy"
         ${build_generator_args}
         --build-project Qt4Deploy
-        --build-options ${build_options}
-        -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
-        -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
+        --build-options
+          -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
+          -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
         )
       list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4Deploy")
     endif()
@@ -590,7 +590,7 @@
     --build-project ExternalDataTest
     --build-noclean
     --force-new-ctest-process
-    --build-options ${build_options}
+    --build-options
       -DMAKE_SUPPORTS_SPACES=${MAKE_SUPPORTS_SPACES}
     --test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} -V
     )
@@ -633,7 +633,6 @@
       "${CMake_BINARY_DIR}/Tests/Visibility"
       ${build_generator_args}
       --build-project Visibility
-      --build-options ${build_options}
     )
     list(APPEND TEST_BUILD_DIRS
       "${CMake_BINARY_DIR}/Tests/Visibility"
@@ -648,7 +647,7 @@
     ${build_generator_args}
     --build-project LinkFlags
     --build-target LinkFlags
-    --build-options ${build_options}
+    --build-options
       -DTEST_CONFIG=\${CTEST_CONFIGURATION_TYPE}
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LinkFlags")
@@ -709,7 +708,6 @@
           --build-generator-platform "${CMAKE_GENERATOR_PLATFORM}"
           --build-generator-toolset "${CMAKE_GENERATOR_TOOLSET}"
           --build-project Simple
-          --build-options ${build_options}
           --test-command Simple)
         list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/${extraGeneratorTestName}")
       endif ()
@@ -729,7 +727,6 @@
       --build-project SubProject
       ${build_generator_args}
       --build-target car
-      --build-options ${build_options}
       --test-command car
       )
 
@@ -755,7 +752,6 @@
       --build-project foo
       --build-target foo
       --build-exe-dir "${CMake_BINARY_DIR}/Tests/SubProject/foo"
-      --build-options ${build_options}
       --test-command foo
       )
     set_tests_properties ( SubProject-Stage2 PROPERTIES DEPENDS SubProject)
@@ -797,7 +793,7 @@
     --build-two-config
     ${build_generator_args}
     --build-project Framework
-    --build-options ${build_options}
+    --build-options
     "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/Framework/Install"
     --test-command bar)
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Framework")
@@ -809,7 +805,6 @@
     --build-two-config
     ${build_generator_args}
     --build-project TargetName
-    --build-options ${build_options}
     --test-command ${CMAKE_CMAKE_COMMAND} -E compare_files
     ${CMake_SOURCE_DIR}/Tests/TargetName/scripts/hello_world
     ${CMake_BINARY_DIR}/Tests/TargetName/scripts/hello_world)
@@ -823,7 +818,6 @@
     ${build_generator_args}
     --build-project LibName
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/LibName/lib"
-    --build-options ${build_options}
     --test-command foobar
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LibName")
@@ -836,7 +830,6 @@
     ${build_generator_args}
     --build-project CustComDepend
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/CustComDepend/bin"
-    --build-options ${build_options}
     --test-command foo bar.c
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustComDepend")
@@ -848,7 +841,6 @@
     ${build_generator_args}
     --build-project ArgumentExpansion
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/ArgumentExpansion/bin"
-    --build-options ${build_options}
     )
   set_tests_properties(ArgumentExpansion PROPERTIES
     FAIL_REGULAR_EXPRESSION "Unexpected: ")
@@ -861,7 +853,7 @@
     "${CMake_BINARY_DIR}/Tests/GeneratorExpression"
     ${build_generator_args}
     --build-project GeneratorExpression
-    --build-options ${build_options}
+    --build-options
       -DCMAKE_BUILD_TYPE=\${CTEST_CONFIGURATION_TYPE}
     --test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE} -V
     )
@@ -875,7 +867,7 @@
     ${build_generator_args}
     --build-project CustomCommand
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/CustomCommand/bin"
-    --build-options ${build_options}
+    --build-options
     --test-command CustomCommand
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustomCommand")
@@ -893,7 +885,6 @@
     --build-two-config
     ${build_generator_args}
     --build-project TestWorkingDir
-    --build-options ${build_options}
     --test-command working
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CustomCommandWorkingDirectory")
@@ -905,7 +896,6 @@
     ${build_generator_args}
     --build-project OutOfSource
     --build-two-config
-    --build-options ${build_options}
     --test-command
     "${CMake_BINARY_DIR}/Tests/OutOfSource/SubDir/OutOfSourceSubdir/simple")
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/OutOfSource")
@@ -918,7 +908,6 @@
     "${CMake_BINARY_DIR}/Tests/BuildDepends"
     ${build_generator_args}
     --build-project BuildDepends
-    --build-options ${build_options}
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BuildDepends")
 
@@ -931,7 +920,7 @@
     ${build_generator_args}
     --build-project TestMissingInstall
     --build-two-config
-    --build-options ${build_options}
+    --build-options
     "-DCMAKE_INSTALL_PREFIX:PATH=${MissingInstallInstallDir}")
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/MissingInstall")
 
@@ -977,7 +966,7 @@
         "${CMake_BINARY_DIR}/Tests/CPackWiXGenerator"
         ${build_generator_args}
         --build-project CPackWiXGenerator
-        --build-options ${build_options}
+        --build-options
         --test-command ${CMAKE_CMAKE_COMMAND}
           "-DCPackWiXGenerator_BINARY_DIR:PATH=${CMake_BINARY_DIR}/Tests/CPackWiXGenerator"
           "-Dconfig=\${CTEST_CONFIGURATION_TYPE}"
@@ -997,7 +986,7 @@
       ${build_generator_args}
       --build-project CPackUseDefaultVersion
       --build-two-config
-      --build-options ${build_options}
+      --build-options
         ${CPackUseDefaultVersion_BUILD_OPTIONS})
     set_tests_properties(CPackUseDefaultVersion PROPERTIES PASS_REGULAR_EXPRESSION "CPACK_PACKAGE_VERSION=0\\.1\\.1")
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackUseDefaultVersion")
@@ -1009,7 +998,7 @@
       ${build_generator_args}
       --build-project CPackUseProjectVersion
       --build-two-config
-      --build-options ${build_options}
+      --build-options
         ${CPackUseProjectVersion_BUILD_OPTIONS})
     set_tests_properties(CPackUseProjectVersion PROPERTIES PASS_REGULAR_EXPRESSION "CPACK_PACKAGE_VERSION=1\\.2\\.3")
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackUseProjectVersion")
@@ -1021,7 +1010,7 @@
       ${build_generator_args}
       --build-project CPackUseShortProjectVersion
       --build-two-config
-      --build-options ${build_options}
+      --build-options
         ${CPackUseProjectVersion_BUILD_OPTIONS})
     set_tests_properties(CPackUseShortProjectVersion PROPERTIES PASS_REGULAR_EXPRESSION "CPACK_PACKAGE_VERSION=2")
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/CPackUseShortProjectVersion")
@@ -1049,7 +1038,7 @@
       --build-project CPackComponents
       --build-two-config
       --build-target package
-      --build-options ${build_options}
+      --build-options
         -DCPACK_BINARY_DEB:BOOL=${CPACK_BINARY_DEB}
         -DCPACK_BINARY_RPM:BOOL=${CPACK_BINARY_RPM}
         ${CPackComponents_BUILD_OPTIONS}
@@ -1109,7 +1098,7 @@
           "${CMake_BINARY_DIR}/Tests/CPackComponentsForAll/build${CPackGen}-${CPackComponentWay}"
           ${build_generator_args}
           --build-project CPackComponentsForAll
-          --build-options ${build_options}
+          --build-options
              -DCPACK_GENERATOR:STRING=${CPACK_GENERATOR_STRING_${CPackGen}}
              -DCPACK_BINARY_${CPackGen}:BOOL=ON
              ${CPackRun_CPackComponentWay}
@@ -1148,7 +1137,7 @@
               "${CMake_BINARY_DIR}/Tests/${DEB_TEST_NAMES}/build${CPackGen}-${CPackDEBConfiguration}"
               ${build_generator_args}
           --build-project CPackComponentsDEB
-          --build-options ${build_options}
+          --build-options
               -DCPACK_GENERATOR:STRING=${CPackGen}
               -DCPACK_BINARY_${CPackGen}:BOOL=ON
               ${CPackRun_CPackDEBConfiguration}
@@ -1188,7 +1177,6 @@
       "${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators"
       ${build_generator_args}
       --build-project CPackTestAllGenerators
-      --build-options ${build_options}
       --test-command
       ${CMAKE_CMAKE_COMMAND}
         -D dir=${CMake_BINARY_DIR}/Tests/CPackTestAllGenerators
@@ -1219,7 +1207,7 @@
       --build-project CPackComponentsPrefix
       --build-two-config
       --build-target package
-      --build-options ${build_options}
+      --build-options
         -DCPACK_BINARY_DEB:BOOL=${CPACK_BINARY_DEB}
         -DCPACK_BINARY_RPM:BOOL=${CPACK_BINARY_RPM}
         -DCPACK_BINARY_ZIP:BOOL=ON
@@ -1242,7 +1230,6 @@
     --build-project UseX11
     --build-two-config
     ${X11_build_target_arg}
-    --build-options ${build_options}
     --test-command  UseX11)
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/X11")
 
@@ -1285,7 +1272,6 @@
       "${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig"
       ${build_generator_args}
       --build-project LoadCommand
-      --build-options ${build_options}
       --test-command  LoadedCommand
       )
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LoadCommandOneConfig")
@@ -1300,7 +1286,6 @@
     ${build_generator_args}
     --build-project Complex
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Complex/bin"
-    --build-options ${build_options}
     -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
     --test-command complex
     )
@@ -1313,7 +1298,6 @@
     ${build_generator_args}
     --build-project Complex
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/ComplexOneConfig/bin"
-    --build-options ${build_options}
     -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
     --test-command complex)
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ComplexOneConfig")
@@ -1328,7 +1312,6 @@
     --build-project EnvironmentProj
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Environment"
     --force-new-ctest-process
-    --build-options ${build_options}
     --test-command ${CMAKE_CTEST_COMMAND} -V
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Environment")
@@ -1339,7 +1322,7 @@
     "${CMake_BINARY_DIR}/Tests/QtAutomocNoQt"
     ${build_generator_args}
     --build-project QtAutomocNoQt
-    --build-options ${build_options}
+    --build-options
       -DCMAKE_BUILD_TYPE=\${CTEST_CONFIGURATION_TYPE}
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomocNoQt")
@@ -1364,7 +1347,7 @@
       --build-project Qt4Targets
       --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4Targets"
       --force-new-ctest-process
-      --build-options ${build_options}
+      --build-options
         -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}
       --test-command ${CMAKE_CTEST_COMMAND} -V
       )
@@ -1379,7 +1362,6 @@
         --build-project Qt4And5Automoc
         --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocForward"
         --force-new-ctest-process
-        --build-options ${build_options}
         --test-command ${CMAKE_CTEST_COMMAND} -V
         )
       list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocForward")
@@ -1391,7 +1373,7 @@
         --build-project Qt4And5Automoc
         --build-exe-dir "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocReverse"
         --force-new-ctest-process
-        --build-options ${build_options} -DQT_REVERSE_FIND_ORDER=1
+        --build-options -DQT_REVERSE_FIND_ORDER=1
         --test-command ${CMAKE_CTEST_COMMAND} -V
         )
       list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Qt4And5AutomocReverse")
@@ -1505,7 +1487,6 @@
     --build-project ExternalProjectTest
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProject"
     --force-new-ctest-process
-    --build-options ${build_options}
     --test-command ${CMAKE_CTEST_COMMAND} -V
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProject")
@@ -1521,7 +1502,6 @@
     ${build_generator_args}
     --build-project ExternalProjectSubdir
     --force-new-ctest-process
-    --build-options ${build_options}
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectSubdir")
 
@@ -1533,7 +1513,6 @@
     ${build_generator_args}
     --build-project ExternalProjectSourceSubdir
     --force-new-ctest-process
-    --build-options ${build_options}
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdir")
 
@@ -1545,7 +1524,6 @@
     ${build_generator_args}
     --build-project ExternalProjectSourceSubdirNotCMake
     --force-new-ctest-process
-    --build-options ${build_options}
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectSourceSubdirNotCMake")
 
@@ -1557,7 +1535,6 @@
     --build-project ExternalProjectLocalTest
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProjectLocal"
     --force-new-ctest-process
-    --build-options ${build_options}
     --test-command ${CMAKE_CTEST_COMMAND} -V
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectLocal")
@@ -1573,7 +1550,6 @@
     --build-project ExternalProjectUpdateTest
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate"
     --force-new-ctest-process
-    --build-options ${build_options}
     --test-command ${CMAKE_CTEST_COMMAND} -V
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ExternalProjectUpdate")
@@ -1615,7 +1591,7 @@
       ${tutorial_build_dir}_Build
       ${build_generator_args}
       --build-project Tutorial
-      --build-options ${build_options} ${tutorial_build_options}
+      --build-options ${tutorial_build_options}
       --test-command Tutorial 25.0)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/${tutorial_build_dir}_Build")
   endfunction()
@@ -1637,7 +1613,6 @@
     "${CMake_BINARY_DIR}/Tests/Testing"
     ${build_generator_args}
     --build-project Testing
-    --build-options ${build_options}
     --test-command ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
     )
   set_tests_properties(testing PROPERTIES PASS_REGULAR_EXPRESSION "Passed")
@@ -1650,7 +1625,6 @@
     ${build_generator_args}
     --build-project Wrapping
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
-    --build-options ${build_options}
     --test-command wrapping
     )
   add_test(qtwrapping  ${CMAKE_CTEST_COMMAND}
@@ -1660,7 +1634,6 @@
     ${build_generator_args}
     --build-project Wrapping
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
-    --build-options ${build_options}
       --test-command qtwrapping
       )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Wrapping")
@@ -1672,7 +1645,6 @@
     ${build_generator_args}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
     --build-project TestDriverTest
-    --build-options ${build_options}
     --test-command TestDriverTest test1
     )
 
@@ -1683,7 +1655,6 @@
     ${build_generator_args}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
     --build-project TestDriverTest
-    --build-options ${build_options}
     --test-command TestDriverTest test2
     )
 
@@ -1694,7 +1665,6 @@
     ${build_generator_args}
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Wrapping/bin"
     --build-project TestDriverTest
-    --build-options ${build_options}
     --test-command TestDriverTest subdir/test3
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestDriver")
@@ -1706,7 +1676,6 @@
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/Dependency/Exec"
     ${build_generator_args}
     --build-project Dependency
-    --build-options ${build_options}
     --test-command exec
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Dependency")
@@ -1736,8 +1705,8 @@
       --build-exe-dir "${CMake_BINARY_DIR}/Tests/Jump/WithLibOut/Executable"
       --build-project Jump
       ${build_generator_args}
-      --build-options ${build_options}
-      -DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Jump/WithLibOut/Lib
+      --build-options
+        -DLIBRARY_OUTPUT_PATH:PATH=${CMake_BINARY_DIR}/Tests/Jump/WithLibOut/Lib
       --test-command jumpExecutable
       )
 
@@ -1749,7 +1718,6 @@
       --build-run-dir "${CMake_BINARY_DIR}/Tests/Jump/NoLibOut/Executable"
       --build-project Jump
       ${build_generator_args}
-      --build-options ${build_options}
       --test-command jumpExecutable
       )
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Jump")
@@ -1761,7 +1729,6 @@
       ${build_generator_args}
       --build-project Plugin
       --build-two-config
-      --build-options ${build_options}
       --test-command bin/example)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Plugin")
 
@@ -1777,7 +1744,7 @@
       "${CMake_BINARY_DIR}/Tests/MacRuntimePath"
       ${build_generator_args}
       --build-project MacRuntimePath
-      --build-options ${build_options}
+      --build-options
         -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM}
       )
   endif()
@@ -1795,7 +1762,6 @@
     "${CMake_BINARY_DIR}/Tests/LinkLineOrder"
     ${build_generator_args}
     --build-project LinkLineOrder
-    --build-options ${build_options}
     --test-command Exec1
     )
 
@@ -1805,7 +1771,6 @@
     "${CMake_BINARY_DIR}/Tests/LinkLineOrder"
     ${build_generator_args}
     --build-project LinkLineOrder
-    --build-options ${build_options}
     --test-command Exec2
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/LinkLineOrder")
@@ -1825,7 +1790,7 @@
       "${CMake_BINARY_DIR}/Tests/LinkStatic"
       ${build_generator_args}
       --build-project LinkStatic
-      --build-options ${build_options}
+      --build-options
         -DMATH_LIBRARY:FILEPATH=/usr/lib/libm.a
       --test-command LinkStatic
       )
@@ -1840,7 +1805,6 @@
       "${CMake_BINARY_DIR}/Tests/SubDirSpaces/Executable Sources"
       ${build_generator_args}
       --build-project SUBDIR
-      --build-options ${build_options}
       --test-command test
       "${CMake_BINARY_DIR}/Tests/SubDirSpaces/ShouldBeHere"
       "${CMake_BINARY_DIR}/Tests/SubDirSpaces/testfromsubdir.obj"
@@ -1856,7 +1820,6 @@
       --build-exe-dir "${CMake_BINARY_DIR}/Tests/SubDir/Executable"
       ${build_generator_args}
       --build-project SUBDIR
-      --build-options ${build_options}
       --test-command test
       "${CMake_BINARY_DIR}/Tests/SubDir/ShouldBeHere"
       "${CMake_BINARY_DIR}/Tests/SubDir/testfromsubdir.obj"
@@ -1869,7 +1832,6 @@
       --build-exe-dir "${CMake_BINARY_DIR}/Tests/SubDir/Executable"
       ${build_generator_args}
       --build-project SUBDIR
-      --build-options ${build_options}
       --test-command test
       "${CMake_BINARY_DIR}/Tests/SubDir/ShouldBeHere"
       "${CMake_BINARY_DIR}/Tests/SubDir/testfromsubdir.o"
@@ -1907,7 +1869,6 @@
       ${build_generator_args}
       --build-project MakeClean
       --build-exe-dir "${CMake_BINARY_DIR}/MakeClean"
-      --build-options ${build_options}
       --test-command check_clean
       )
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/MakeClean")
@@ -2016,7 +1977,6 @@
       --build-two-config
       ${build_generator_args}
       --build-project mfc_driver
-      --build-options ${build_options}
       --test-command ${CMAKE_CTEST_COMMAND}
         -C \${CTEST_CONFIGURATION_TYPE} -VV)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/MFC")
@@ -2046,7 +2006,6 @@
       --build-two-config
       ${build_generator_args}
       --build-project VSExternalInclude
-      --build-options ${build_options}
       --test-command VSExternalInclude)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSExternalInclude")
 
@@ -2057,7 +2016,6 @@
       --build-two-config
       ${build_generator_args}
       --build-project VSMidl
-      --build-options ${build_options}
       --test-command VSMidl)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/VSMidl")
 
@@ -2344,7 +2302,7 @@
         --build-project BundleTest
         --build-target install
 #       --build-target package
-        --build-options ${build_options}
+        --build-options
         "-DCMAKE_INSTALL_PREFIX:PATH=${BundleTestInstallDir}"
         "-DCMake_SOURCE_DIR:PATH=${CMake_SOURCE_DIR}"
         --test-command
@@ -2359,7 +2317,6 @@
         ${build_generator_args}
         --build-project CFBundleTest
         --build-config $<CONFIGURATION>
-        --build-options ${build_options}
         --test-command
         ${CMAKE_CMAKE_COMMAND} -DCTEST_CONFIGURATION_TYPE=$<CONFIGURATION>
         -Ddir=${CMake_BINARY_DIR}/Tests/CFBundleTest
@@ -2380,7 +2337,7 @@
       ${build_generator_args}
       --build-project BundleGeneratorTest
       --build-target package
-      --build-options ${build_options}
+      --build-options
         "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/BundleGeneratorTest/InstallDirectory"
       )
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/BundleGeneratorTest")
@@ -2393,7 +2350,7 @@
     ${build_generator_args}
     --build-noclean
     --build-project WarnUnusedUnusedViaSet
-    --build-options ${build_options}
+    --build-options
       "--warn-unused-vars")
   set_tests_properties(WarnUnusedUnusedViaSet PROPERTIES
     PASS_REGULAR_EXPRESSION "unused variable \\(changing definition\\) 'UNUSED_VARIABLE'")
@@ -2408,7 +2365,7 @@
     ${build_generator_args}
     --build-noclean
     --build-project WarnUnusedUnusedViaUnset
-    --build-options ${build_options}
+    --build-options
       "--warn-unused-vars")
   set_tests_properties(WarnUnusedUnusedViaUnset PROPERTIES
     PASS_REGULAR_EXPRESSION "CMake Warning \\(dev\\) at CMakeLists.txt:7 \\(set\\):")
@@ -2422,7 +2379,7 @@
     "${CMake_BINARY_DIR}/Tests/WarnUnusedCliUnused"
     ${build_generator_args}
     --build-project WarnUnusedCliUnused
-    --build-options ${build_options}
+    --build-options
       "-DUNUSED_CLI_VARIABLE=Unused")
   set_tests_properties(WarnUnusedCliUnused PROPERTIES
     PASS_REGULAR_EXPRESSION "CMake Warning:.*Manually-specified variables were not used by the project:.*  UNUSED_CLI_VARIABLE")
@@ -2435,7 +2392,7 @@
     ${build_generator_args}
     --build-noclean
     --build-project WarnUnusedCliUsed
-    --build-options ${build_options}
+    --build-options
       "-DUSED_VARIABLE=Usage proven")
   set_tests_properties(WarnUnusedCliUsed PROPERTIES
     PASS_REGULAR_EXPRESSION "Usage proven")
@@ -2450,7 +2407,7 @@
     ${build_generator_args}
     --build-noclean
     --build-project WarnUninitialized
-    --build-options ${build_options}
+    --build-options
       "--warn-uninitialized")
   set_tests_properties(WarnUninitialized PROPERTIES
     PASS_REGULAR_EXPRESSION "uninitialized variable 'USED_VARIABLE'")
@@ -2465,7 +2422,6 @@
     --build-project TestsWorkingDirectoryProj
     --build-exe-dir "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory"
     --force-new-ctest-process
-    --build-options ${build_options}
     --test-command ${CMAKE_CTEST_COMMAND} -V -C \${CTEST_CONFIGURATION_TYPE}
     )
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/TestsWorkingDirectory")
@@ -3263,7 +3219,6 @@
       ${build_generator_args}
       --build-project testf
       --build-two-config
-      --build-options ${build_options}
       --test-command testf)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Fortran")
 
@@ -3274,7 +3229,7 @@
         "${CMake_BINARY_DIR}/Tests/FortranModules"
         ${build_generator_args}
         --build-project FortranModules
-        --build-options ${build_options}
+        --build-options
           -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM}
           -DCMake_TEST_Fortran_SUBMODULES:BOOL=${CMake_TEST_Fortran_SUBMODULES}
           ${CMake_TEST_FortranModules_BUILD_OPTIONS}
@@ -3297,7 +3252,6 @@
         ${build_generator_args}
         --build-project FortranC
         --build-two-config
-        --build-options ${build_options}
         --test-command CMakeFiles/FortranCInterface/FortranCInterface)
       list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/FortranC")
     endif()
@@ -3326,7 +3280,6 @@
           --build-target hello
           --build-two-config
           --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJar/"
-          --build-options ${build_options}
           --test-command ${JAVA_RUNTIME} -classpath hello.jar HelloWorld)
         list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJar")
         add_test(Java.JarSourceList ${CMAKE_CTEST_COMMAND}
@@ -3338,7 +3291,6 @@
           --build-target hello2
           --build-two-config
           --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJarSourceList/"
-          --build-options ${build_options}
           --test-command ${JAVA_RUNTIME} -classpath hello2.jar HelloWorld)
         list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJarSourceList")
         add_test(Java.JarSourceListAndOutput ${CMAKE_CTEST_COMMAND}
@@ -3350,7 +3302,6 @@
           --build-target hello3
           --build-two-config
           --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJarSourceListAndOutput/hello3"
-          --build-options ${build_options}
           --test-command ${JAVA_RUNTIME} -classpath hello3.jar HelloWorld)
         list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJarSourceListAndOutput")
 
@@ -3376,7 +3327,6 @@
               --build-project helloJavah
               --build-two-config
               --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJavah/"
-              --build-options ${build_options}
               --test-command ${JAVA_RUNTIME} -Djava.library.path=${JAVAH_LIBRARY_PATH} -classpath hello3.jar HelloWorld2)
             list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJavah")
           endif()
@@ -3395,7 +3345,6 @@
               --build-project helloJavaNativeHeaders
               --build-two-config
               --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders/"
-              --build-options ${build_options}
               --test-command ${JAVA_RUNTIME} -Djava.library.path=${JAVANATIVEHEADERS_LIBRARY_PATH} -classpath hello4.jar HelloWorld3)
             list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders")
           endif()
@@ -3417,9 +3366,9 @@
         "${CMake_BINARY_DIR}/Tests/SimpleCOnly_sdcc"
         ${build_generator_args}
         --build-project SimpleC
-        --build-options ${build_options}
-        "-DCMAKE_SYSTEM_NAME=Generic"
-        "-DCMAKE_C_COMPILER=${SDCC_EXECUTABLE}")
+        --build-options
+          "-DCMAKE_SYSTEM_NAME=Generic"
+          "-DCMAKE_C_COMPILER=${SDCC_EXECUTABLE}")
       list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/SimpleCOnly_sdcc")
     endif()
 
@@ -3435,11 +3384,11 @@
         "${CMake_BINARY_DIR}/Tests/Simple_Mingw_Linux2Win"
         ${build_generator_args}
         --build-project Simple
-        --build-options ${build_options}
-        "-DCMAKE_SYSTEM_NAME=Windows"
-        "-DCMAKE_C_COMPILER=${MINGW_CC_LINUX2WIN_EXECUTABLE}"
-        "-DCMAKE_CXX_COMPILER=${MINGW_CXX_LINUX2WIN_EXECUTABLE}"
-        "-DCMAKE_RC_COMPILER=${MINGW_RC_LINUX2WIN_EXECUTABLE}"
+        --build-options
+          "-DCMAKE_SYSTEM_NAME=Windows"
+          "-DCMAKE_C_COMPILER=${MINGW_CC_LINUX2WIN_EXECUTABLE}"
+          "-DCMAKE_CXX_COMPILER=${MINGW_CXX_LINUX2WIN_EXECUTABLE}"
+          "-DCMAKE_RC_COMPILER=${MINGW_RC_LINUX2WIN_EXECUTABLE}"
         )
       list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Simple_Mingw_Linux2Win")
     endif()
@@ -3525,7 +3474,6 @@
     --build-two-config
     ${build_generator_args}
     --build-project IncludeDirectories
-    --build-options ${build_options}
     --test-command IncludeDirectories)
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/IncludeDirectories")
 
@@ -3539,8 +3487,7 @@
       "${CMake_BINARY_DIR}/Tests/IncludeDirectoriesCPATH"
       --build-two-config
       ${build_generator_args}
-      --build-project IncludeDirectoriesCPATH
-      --build-options ${build_options})
+      --build-project IncludeDirectoriesCPATH)
     list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/IncludeDirectoriesCPATH")
     set_tests_properties(IncludeDirectoriesCPATH
       PROPERTIES
@@ -3554,7 +3501,6 @@
     --build-two-config
     ${build_generator_args}
     --build-project InterfaceLinkLibraries
-    --build-options ${build_options}
     --test-command InterfaceLinkLibraries)
   list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/InterfaceLinkLibraries")
 
diff --git a/Tests/CMakeTests/ELFTest.cmake.in b/Tests/CMakeTests/ELFTest.cmake.in
index 4635778..85c2360 100644
--- a/Tests/CMakeTests/ELFTest.cmake.in
+++ b/Tests/CMakeTests/ELFTest.cmake.in
@@ -25,11 +25,36 @@
   # Change the RPATH.
   file(RPATH_CHANGE FILE "${f}"
     OLD_RPATH "/sample/rpath"
-    NEW_RPATH "/rpath/sample")
+    NEW_RPATH "/path1:/path2")
+  set(rpath)
+  file(STRINGS "${f}" rpath REGEX "/path1:/path2" LIMIT_COUNT 1)
+  if(NOT rpath)
+    message(FATAL_ERROR "RPATH not changed in ${f}")
+  endif()
+
+  # Change the RPATH without compiler defined rpath removed
+  file(RPATH_CHANGE FILE "${f}"
+    OLD_RPATH "/path2"
+    NEW_RPATH "/path3")
+  set(rpath)
+  file(STRINGS "${f}" rpath REGEX "/path1:/path3" LIMIT_COUNT 1)
+  if(NOT rpath)
+    message(FATAL_ERROR "RPATH not updated in ${f}")
+  endif()
+
+  # Change the RPATH with compiler defined rpath removed
+  file(RPATH_CHANGE FILE "${f}"
+    OLD_RPATH "/path3"
+    NEW_RPATH "/rpath/sample"
+    INSTALL_REMOVE_ENVIRONMENT_RPATH)
   set(rpath)
   file(STRINGS "${f}" rpath REGEX "/rpath/sample" LIMIT_COUNT 1)
   if(NOT rpath)
-    message(FATAL_ERROR "RPATH not changed in ${f}")
+    message(FATAL_ERROR "RPATH not updated in ${f}")
+  endif()
+  file(STRINGS "${f}" rpath REGEX "/path1" LIMIT_COUNT 1)
+  if(rpath)
+    message(FATAL_ERROR "RPATH not removed in ${f}")
   endif()
 
   # Remove the RPATH.
diff --git a/Tests/Complex/CMakeLists.txt b/Tests/Complex/CMakeLists.txt
index fef83f6..2e41754 100644
--- a/Tests/Complex/CMakeLists.txt
+++ b/Tests/Complex/CMakeLists.txt
@@ -446,11 +446,6 @@
   set(CMAKE_CXX_STANDARD 11)
 endif()
 
-if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
-    CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
-  set(CMAKE_CXX_STANDARD 14)
-endif()
-
 #
 # Create the libs and the main exe
 #
diff --git a/Tests/ComplexOneConfig/CMakeLists.txt b/Tests/ComplexOneConfig/CMakeLists.txt
index 77baa4c..628cd4e 100644
--- a/Tests/ComplexOneConfig/CMakeLists.txt
+++ b/Tests/ComplexOneConfig/CMakeLists.txt
@@ -403,11 +403,6 @@
   set(CMAKE_CXX_STANDARD 11)
 endif()
 
-if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
-    CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
-  set(CMAKE_CXX_STANDARD 14)
-endif()
-
 #
 # Create the libs and the main exe
 #
diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt
index 5adcbd9..093391e 100644
--- a/Tests/ExternalProject/CMakeLists.txt
+++ b/Tests/ExternalProject/CMakeLists.txt
@@ -421,7 +421,7 @@
 
   set(local_git_repo "../../LocalRepositories/GIT-with-submodules")
 
-  set(proj TS1-GIT-no-GIT_SUBMODULES)
+  set(proj TS1-GIT-all-GIT_SUBMODULES)
   ExternalProject_Add(${proj}
     GIT_REPOSITORY "${local_git_repo}"
     CMAKE_GENERATOR "${CMAKE_GENERATOR}"
@@ -435,7 +435,8 @@
   )
   set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
 
-  set(proj TS1-GIT-empty-GIT_SUBMODULES)
+  set(proj TS1-GIT-all-GIT_SUBMODULES-via-CMP0097-OLD)
+  cmake_policy(SET CMP0097 OLD)
   ExternalProject_Add(${proj}
     GIT_REPOSITORY "${local_git_repo}"
     GIT_SUBMODULES ""
@@ -450,6 +451,22 @@
   )
   set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
 
+  set(proj TS1-GIT-no-GIT_SUBMODULES)
+  cmake_policy(SET CMP0097 NEW)
+  ExternalProject_Add(${proj}
+    GIT_REPOSITORY "${local_git_repo}"
+    GIT_SUBMODULES ""
+    CMAKE_GENERATOR "${CMAKE_GENERATOR}"
+    CMAKE_ARGS -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
+               -DWITH_m1:BOOL=OFF
+               -DWITH_m2:BOOL=OFF
+    BUILD_COMMAND ""
+    INSTALL_COMMAND ""
+    DEPENDS "SetupLocalGITRepository"
+            "SetupLocalGITRepositoryWithSubmodules"
+  )
+  set_property(TARGET ${proj} PROPERTY FOLDER "GIT")
+
   set(proj TS1-GIT-some-GIT_SUBMODULES)
   ExternalProject_Add(${proj}
     GIT_REPOSITORY "${local_git_repo}"
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt
index 2f0c051..519608c 100644
--- a/Tests/FindPackageTest/CMakeLists.txt
+++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -607,6 +607,26 @@
 
 set(CMAKE_FIND_PACKAGE_PREFER_CONFIG OFF)
 set(CMAKE_PREFIX_PATH)
+set(CMAKE_MODULE_PATH)
+
+############################################################################
+##Test FIND_PACKAGE CMAKE_FIND_PACKAGE_PREFER_CONFIG - Do not recurse
+
+# No CMAKE_PREFIX_PATH
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/PreferConfigRecurse)
+
+# Now prefer config mode
+set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
+unset(ACME_FOUND)
+unset(ACME_CONFIG)
+
+find_package(ACME)
+if(ACME_FOUND AND ACME_CONFIG)
+    message(SEND_ERROR "Incorrectly found ACME in CONFIG mode, from the MODULE package")
+endif()
+
+set(CMAKE_FIND_PACKAGE_PREFER_CONFIG OFF)
+set(CMAKE_MODULE_PATH)
 
 ############################################################################
 ##Test find_package CMAKE_FIND_PACKAGE_PREFER_CONFIG with module fallback
@@ -620,3 +640,16 @@
 if(NOT ACME_FOUND)
     message(SEND_ERROR "Did not find ACME package")
 endif()
+
+############################################################################
+##Test find_package CMAKE_FIND_PACKAGE_PREFER_CONFIG with NO_MODULE
+
+set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/PreferConfigOnlyModule)
+
+set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
+
+find_package(ACME NO_MODULE)
+
+if(ACME_FOUND)
+    message(SEND_ERROR "Should not find ACME package")
+endif()
diff --git a/Tests/FindPackageTest/PreferConfigRecurse/ACMEConfig.cmake b/Tests/FindPackageTest/PreferConfigRecurse/ACMEConfig.cmake
new file mode 100644
index 0000000..7a4e1b3
--- /dev/null
+++ b/Tests/FindPackageTest/PreferConfigRecurse/ACMEConfig.cmake
@@ -0,0 +1 @@
+set(ACME_FOUND TRUE)
diff --git a/Tests/FindPackageTest/PreferConfigRecurse/FindACME.cmake b/Tests/FindPackageTest/PreferConfigRecurse/FindACME.cmake
new file mode 100644
index 0000000..9bdc7db
--- /dev/null
+++ b/Tests/FindPackageTest/PreferConfigRecurse/FindACME.cmake
@@ -0,0 +1 @@
+find_package(ACME NO_MODULE)
diff --git a/Tests/MathTest/CMakeLists.txt b/Tests/MathTest/CMakeLists.txt
index 5403d29..396f633 100644
--- a/Tests/MathTest/CMakeLists.txt
+++ b/Tests/MathTest/CMakeLists.txt
@@ -16,6 +16,8 @@
   "1000 -12*5"
   "1000 +12*-5"
   "1000 -12*-5"
+  "~~1"
+  "1000 & ~0"
   )
 
 set(FILE_EXPRESSIONS "extern void test_expression(int x, int y, const char * text);\n")
diff --git a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt
index b30928d..cffef5a 100644
--- a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt
+++ b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt
@@ -133,9 +133,7 @@
 
 # for msvc the compiler version determines which c++11 features are available.
 if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC"
-    OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang"
-    AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC"
-    AND "x${CMAKE_CXX_COMPILER_FRONTEND_VARIANT}" STREQUAL "xMSVC" ))
+    OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND "x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC"))
   if(";${CMAKE_CXX_COMPILE_FEATURES};" MATCHES ";cxx_delegating_constructors;")
     list(APPEND true_defs EXPECTED_COMPILER_CXX_DELEGATING_CONSTRUCTORS)
     list(APPEND true_defs EXPECTED_COMPILER_CXX_VARIADIC_TEMPLATES)
diff --git a/Tests/Plugin/CMakeLists.txt b/Tests/Plugin/CMakeLists.txt
index c4540db..8e8fa07 100644
--- a/Tests/Plugin/CMakeLists.txt
+++ b/Tests/Plugin/CMakeLists.txt
@@ -5,17 +5,6 @@
 # We need proper C++98 support from the compiler
 set(CMAKE_CXX_STANDARD 98)
 
-# Clang/C2 in C++98 mode cannot properly handle some of MSVC headers
-if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
-    CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
-  set(CMAKE_CXX_STANDARD 11)
-endif()
-
-if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
-    CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
-  set(CMAKE_CXX_STANDARD 14)
-endif()
-
 # Test per-target output directory properties.
 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${Plugin_BINARY_DIR}/bin)
 set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${Plugin_BINARY_DIR}/lib/plugin)
@@ -40,6 +29,12 @@
   ${Plugin_SOURCE_DIR}/include
   )
 
+# Clang/C2 in C++98 mode cannot properly handle some of MSVC headers
+if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
+    CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC")
+  set(CMAKE_CXX_STANDARD 11)
+endif()
+
 # Create an executable that exports an API for use by plugins.
 add_executable(example_exe src/example_exe.cxx)
 set_target_properties(example_exe PROPERTIES
diff --git a/Tests/RunCMake/Android/common.cmake b/Tests/RunCMake/Android/common.cmake
index aaa7c89..d96ab86 100644
--- a/Tests/RunCMake/Android/common.cmake
+++ b/Tests/RunCMake/Android/common.cmake
@@ -6,8 +6,6 @@
 endif()
 
 foreach(f
-    "${CMAKE_C_ANDROID_TOOLCHAIN_PREFIX}gcc${CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX}"
-    "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}g++${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}"
     "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}ar${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}"
     "${CMAKE_CXX_ANDROID_TOOLCHAIN_PREFIX}ld${CMAKE_CXX_ANDROID_TOOLCHAIN_SUFFIX}"
     )
@@ -51,23 +49,26 @@
   endif()
 endif()
 
-execute_process(
-  COMMAND "${CMAKE_C_ANDROID_TOOLCHAIN_PREFIX}gcc${CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX}" -dumpmachine
-  OUTPUT_VARIABLE _out OUTPUT_STRIP_TRAILING_WHITESPACE
-  ERROR_VARIABLE _err
-  RESULT_VARIABLE _res
-  )
-if(NOT _res EQUAL 0)
-  message(SEND_ERROR "Failed to run 'gcc -dumpmachine':\n ${_res}")
-endif()
-string(REPLACE "--" "-" _out_check "${_out}")
-if(NOT _out_check STREQUAL "${CMAKE_C_ANDROID_TOOLCHAIN_MACHINE}"
-    AND NOT (_out STREQUAL "arm--linux-android" AND CMAKE_C_ANDROID_TOOLCHAIN_MACHINE STREQUAL "arm-linux-androideabi"))
-  message(SEND_ERROR "'gcc -dumpmachine' produced:\n"
-    " ${_out}\n"
-    "which does not match CMAKE_C_ANDROID_TOOLCHAIN_MACHINE:\n"
-    " ${CMAKE_C_ANDROID_TOOLCHAIN_MACHINE}"
+set(gcc ${CMAKE_C_ANDROID_TOOLCHAIN_PREFIX}gcc${CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX})
+if(EXISTS "${gcc}")
+  execute_process(
+    COMMAND "${CMAKE_C_ANDROID_TOOLCHAIN_PREFIX}gcc${CMAKE_C_ANDROID_TOOLCHAIN_SUFFIX}" -dumpmachine
+    OUTPUT_VARIABLE _out OUTPUT_STRIP_TRAILING_WHITESPACE
+    ERROR_VARIABLE _err
+    RESULT_VARIABLE _res
     )
+  if(NOT _res EQUAL 0)
+    message(SEND_ERROR "Failed to run 'gcc -dumpmachine':\n ${_res}")
+  endif()
+  string(REPLACE "--" "-" _out_check "${_out}")
+  if(NOT _out_check STREQUAL "${CMAKE_C_ANDROID_TOOLCHAIN_MACHINE}"
+      AND NOT (_out STREQUAL "arm--linux-android" AND CMAKE_C_ANDROID_TOOLCHAIN_MACHINE STREQUAL "arm-linux-androideabi"))
+    message(SEND_ERROR "'gcc -dumpmachine' produced:\n"
+      " ${_out}\n"
+      "which does not match CMAKE_C_ANDROID_TOOLCHAIN_MACHINE:\n"
+      " ${CMAKE_C_ANDROID_TOOLCHAIN_MACHINE}"
+      )
+  endif()
 endif()
 
 if(CMAKE_ANDROID_STL_TYPE STREQUAL "none")
diff --git a/Tests/RunCMake/Android/ndk-arm64-v8a-stdout.txt b/Tests/RunCMake/Android/ndk-arm64-v8a-stdout.txt
index 8d0bdc2..a228ccc 100644
--- a/Tests/RunCMake/Android/ndk-arm64-v8a-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-arm64-v8a-stdout.txt
@@ -1,2 +1,2 @@
 -- Android: Targeting API '[0-9]+' with architecture 'arm64', ABI 'arm64-v8a', and processor 'aarch64'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
diff --git a/Tests/RunCMake/Android/ndk-armeabi-arm-stdout.txt b/Tests/RunCMake/Android/ndk-armeabi-arm-stdout.txt
index 3741da3..72ec00e 100644
--- a/Tests/RunCMake/Android/ndk-armeabi-arm-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-armeabi-arm-stdout.txt
@@ -1,3 +1,3 @@
 -- Android: Targeting API '[0-9]+' with architecture 'arm', ABI 'armeabi', and processor 'armv5te'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
 .*-- CMAKE_ANDROID_ARM_MODE=1
diff --git a/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stdout.txt b/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stdout.txt
index ac2bfd5..8bd87fa 100644
--- a/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-armeabi-v7a-neon-stdout.txt
@@ -1,3 +1,3 @@
 -- Android: Targeting API '[0-9]+' with architecture 'arm', ABI 'armeabi-v7a', and processor 'armv7-a'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
 .*-- CMAKE_ANDROID_ARM_NEON=1
diff --git a/Tests/RunCMake/Android/ndk-armeabi-v7a-stdout.txt b/Tests/RunCMake/Android/ndk-armeabi-v7a-stdout.txt
index 0edb4f7..554548e 100644
--- a/Tests/RunCMake/Android/ndk-armeabi-v7a-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-armeabi-v7a-stdout.txt
@@ -1,3 +1,3 @@
 -- Android: Targeting API '[0-9]+' with architecture 'arm', ABI 'armeabi-v7a', and processor 'armv7-a'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
 .*-- CMAKE_ANDROID_ARM_NEON=0
diff --git a/Tests/RunCMake/Android/ndk-badver-stderr.txt b/Tests/RunCMake/Android/ndk-badver-stderr.txt
index df2c5e6..ce6bc4e 100644
--- a/Tests/RunCMake/Android/ndk-badver-stderr.txt
+++ b/Tests/RunCMake/Android/ndk-badver-stderr.txt
@@ -1,11 +1,12 @@
 ^CMake Error at .*/Modules/Platform/Android/Determine-Compiler-NDK.cmake:[0-9]+ \(message\):
-  Android: The CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION value 'badver' is not one
+  Android: The CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION value 'badver' is not(
+  supported by this NDK.  It must be 'clang' or not set at all\.| one
   of the allowed forms:
 
     <major>.<minor>       = GCC of specified version
     clang<major>.<minor>  = Clang of specified version
     clang                 = Clang of most recent available version
-
+)
 Call Stack \(most recent call first\):
 .*
   ndk-badver.cmake:1 \(enable_language\)
diff --git a/Tests/RunCMake/Android/ndk-badvernum-stderr.txt b/Tests/RunCMake/Android/ndk-badvernum-stderr.txt
index adacaf1..aec91d9 100644
--- a/Tests/RunCMake/Android/ndk-badvernum-stderr.txt
+++ b/Tests/RunCMake/Android/ndk-badvernum-stderr.txt
@@ -1,4 +1,6 @@
-^CMake Error at .*/Modules/Platform/Android/Determine-Compiler-NDK.cmake:[0-9]+ \(message\):
+^CMake Error at .*/Modules/Platform/Android/Determine-Compiler-NDK.cmake:[0-9]+ \(message\):(
+  Android: The CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION value '1.0' is not
+  supported by this NDK.  It must be 'clang' or not set at all.|
   Android: No toolchain for ABI 'armeabi(-v7a)?' found in the NDK:
 
     .*
@@ -6,7 +8,7 @@
   of the version specified by CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION:
 
     1\.0
-
+)
 Call Stack \(most recent call first\):
 .*
   ndk-badvernum.cmake:1 \(enable_language\)
diff --git a/Tests/RunCMake/Android/ndk-mips-stdout.txt b/Tests/RunCMake/Android/ndk-mips-stdout.txt
index c744683..8ce544d 100644
--- a/Tests/RunCMake/Android/ndk-mips-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-mips-stdout.txt
@@ -1,2 +1,2 @@
 -- Android: Targeting API '[0-9]+' with architecture 'mips', ABI 'mips', and processor 'mips'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
diff --git a/Tests/RunCMake/Android/ndk-mips64-stdout.txt b/Tests/RunCMake/Android/ndk-mips64-stdout.txt
index 839ddfd..1d7edea 100644
--- a/Tests/RunCMake/Android/ndk-mips64-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-mips64-stdout.txt
@@ -1,2 +1,2 @@
 -- Android: Targeting API '[0-9]+' with architecture 'mips64', ABI 'mips64', and processor 'mips64'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
diff --git a/Tests/RunCMake/Android/ndk-x86-stdout.txt b/Tests/RunCMake/Android/ndk-x86-stdout.txt
index 2dbb2f0..8d710fe 100644
--- a/Tests/RunCMake/Android/ndk-x86-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-x86-stdout.txt
@@ -1,2 +1,2 @@
 -- Android: Targeting API '[0-9]+' with architecture 'x86', ABI 'x86', and processor 'i686'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
diff --git a/Tests/RunCMake/Android/ndk-x86_64-stdout.txt b/Tests/RunCMake/Android/ndk-x86_64-stdout.txt
index a7ae91d..695a088 100644
--- a/Tests/RunCMake/Android/ndk-x86_64-stdout.txt
+++ b/Tests/RunCMake/Android/ndk-x86_64-stdout.txt
@@ -1,2 +1,2 @@
 -- Android: Targeting API '[0-9]+' with architecture 'x86_64', ABI 'x86_64', and processor 'x86_64'
--- Android: Selected (Clang toolchain '[^']+' with )?GCC toolchain '[^']+'
+-- Android: Selected (unified Clang toolchain|(Clang toolchain '[^']+' with )?GCC toolchain '[^']+')
diff --git a/Tests/RunCMake/BuildDepends/BuildUnderSource.c b/Tests/RunCMake/BuildDepends/BuildUnderSource.c
new file mode 100644
index 0000000..688a040
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/BuildUnderSource.c
@@ -0,0 +1,5 @@
+#include "BuildUnderSource.h"
+int main(void)
+{
+  return BUILD_UNDER_SOURCE;
+}
diff --git a/Tests/RunCMake/BuildDepends/BuildUnderSource.cmake b/Tests/RunCMake/BuildDepends/BuildUnderSource.cmake
new file mode 100644
index 0000000..aa2a44f
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/BuildUnderSource.cmake
@@ -0,0 +1,9 @@
+enable_language(C)
+include_directories(include)
+add_executable(BuildUnderSource BuildUnderSource.c)
+
+file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
+set(check_pairs
+  \"$<TARGET_FILE:BuildUnderSource>|${CMAKE_CURRENT_SOURCE_DIR}/include/BuildUnderSource.h\"
+  )
+")
diff --git a/Tests/RunCMake/BuildDepends/BuildUnderSource.step1.cmake b/Tests/RunCMake/BuildDepends/BuildUnderSource.step1.cmake
new file mode 100644
index 0000000..2cdd32b
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/BuildUnderSource.step1.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_SOURCE_DIR}/include/BuildUnderSource.h" [[
+#define BUILD_UNDER_SOURCE 1
+]])
diff --git a/Tests/RunCMake/BuildDepends/BuildUnderSource.step2.cmake b/Tests/RunCMake/BuildDepends/BuildUnderSource.step2.cmake
new file mode 100644
index 0000000..8e4b858
--- /dev/null
+++ b/Tests/RunCMake/BuildDepends/BuildUnderSource.step2.cmake
@@ -0,0 +1,3 @@
+file(WRITE "${RunCMake_TEST_SOURCE_DIR}/include/BuildUnderSource.h" [[
+#define BUILD_UNDER_SOURCE 2
+]])
diff --git a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
index 3445beb..14ae243 100644
--- a/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
+++ b/Tests/RunCMake/BuildDepends/RunCMakeTest.cmake
@@ -9,7 +9,9 @@
 
 function(run_BuildDepends CASE)
   # Use a single build tree for a few tests without cleaning.
-  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${CASE}-build)
+  if(NOT RunCMake_TEST_BINARY_DIR)
+    set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${CASE}-build)
+  endif()
   set(RunCMake_TEST_NO_CLEAN 1)
   if(NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
     set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
@@ -44,6 +46,18 @@
 run_BuildDepends(Custom-Symbolic-and-Byproduct)
 run_BuildDepends(Custom-Always)
 
+# Test header dependencies with a build tree underneath a source tree.
+set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/BuildUnderSource")
+set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/BuildUnderSource/build")
+file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}")
+file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}/include")
+foreach(f CMakeLists.txt BuildUnderSource.cmake BuildUnderSource.c)
+  configure_file("${RunCMake_SOURCE_DIR}/${f}" "${RunCMake_TEST_SOURCE_DIR}/${f}" COPYONLY)
+endforeach()
+run_BuildDepends(BuildUnderSource)
+unset(RunCMake_TEST_BINARY_DIR)
+unset(RunCMake_TEST_SOURCE_DIR)
+
 if(RunCMake_GENERATOR MATCHES "Make")
   run_BuildDepends(MakeCustomIncludes)
   if(NOT "${RunCMake_BINARY_DIR}" STREQUAL "${RunCMake_SOURCE_DIR}")
diff --git a/Tests/RunCMake/CMP0065/RunCMakeTest.cmake b/Tests/RunCMake/CMP0065/RunCMakeTest.cmake
index 254a4ec..e86b50e 100644
--- a/Tests/RunCMake/CMP0065/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMP0065/RunCMakeTest.cmake
@@ -1,8 +1,11 @@
 include(RunCMake)
 
 run_cmake(OLDBad1)
-run_cmake(OLDBad2)
-run_cmake(NEWBad)
+if(NOT CMAKE_SYSTEM_NAME STREQUAL "AIX")
+  # Tests with ENABLE_EXPORTS ON.  For AIX we do not use the flags at all.
+  run_cmake(OLDBad2)
+  run_cmake(NEWBad)
+endif()
 run_cmake(NEWGood)
 run_cmake(WARN-OFF)
 run_cmake(WARN-ON)
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 735ad5f..c952b1a 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -120,7 +120,7 @@
 # CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS variable, which both the VS and Xcode
 # generators ignore.  The policy will have no effect on those generators.
 if(NOT CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
-  add_RunCMake_test(CMP0065)
+  add_RunCMake_test(CMP0065 -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
 endif()
 if(CMAKE_GENERATOR MATCHES "Make")
   add_RunCMake_test(Make -DMAKE_IS_GNU=${MAKE_IS_GNU})
diff --git a/Tests/RunCMake/CPack/RunCMakeTest.cmake b/Tests/RunCMake/CPack/RunCMakeTest.cmake
index 37df57c..d93f280 100644
--- a/Tests/RunCMake/CPack/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CPack/RunCMakeTest.cmake
@@ -33,6 +33,6 @@
 unset(ENVIRONMENT)
 run_cpack_test(USER_FILELIST "RPM.USER_FILELIST" false "MONOLITHIC")
 run_cpack_test(MD5SUMS "DEB.MD5SUMS" false "MONOLITHIC;COMPONENT")
-run_cpack_test(CPACK_INSTALL_SCRIPT "ZIP" false "MONOLITHIC")
+run_cpack_test_subtests(CPACK_INSTALL_SCRIPTS "singular;plural;both" "ZIP" false "MONOLITHIC")
 run_cpack_test(DEB_PACKAGE_VERSION_BACK_COMPATIBILITY "DEB.DEB_PACKAGE_VERSION_BACK_COMPATIBILITY" false "MONOLITHIC;COMPONENT")
 run_cpack_test_subtests(EXTERNAL "none;good;good_multi;bad_major;bad_minor;invalid_good;invalid_bad;stage_and_package" "External" false "MONOLITHIC;COMPONENT")
diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/test.cmake b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/test.cmake
deleted file mode 100644
index e3fe0ca..0000000
--- a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/test.cmake
+++ /dev/null
@@ -1,11 +0,0 @@
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/abc.txt" "test content")
-file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/user-script.cmake"
-  "file(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/foo\"
-    TYPE FILE FILES \"${CMAKE_CURRENT_BINARY_DIR}/abc.txt\")")
-set(CPACK_INSTALL_SCRIPT "${CMAKE_CURRENT_BINARY_DIR}/user-script.cmake")
-
-function(run_after_include_cpack)
-  file(READ "${CPACK_OUTPUT_CONFIG_FILE}" conf_file_)
-  string(REGEX REPLACE "SET\\(CPACK_INSTALL_CMAKE_PROJECTS [^)]*\\)" "" conf_file_ "${conf_file_}")
-  file(WRITE "${CPACK_OUTPUT_CONFIG_FILE}" "${conf_file_}")
-endfunction()
diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/ExpectedFiles.cmake b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/ExpectedFiles.cmake
similarity index 100%
rename from Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPT/ExpectedFiles.cmake
rename to Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/ExpectedFiles.cmake
diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/both-stderr.txt b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/both-stderr.txt
new file mode 100644
index 0000000..666030e
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/both-stderr.txt
@@ -0,0 +1 @@
+CPack Warning: Both CPACK_INSTALL_SCRIPTS and CPACK_INSTALL_SCRIPT are set, the latter will be ignored.
diff --git a/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/test.cmake b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/test.cmake
new file mode 100644
index 0000000..249d2e6
--- /dev/null
+++ b/Tests/RunCMake/CPack/tests/CPACK_INSTALL_SCRIPTS/test.cmake
@@ -0,0 +1,26 @@
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/abc.txt" "test content")
+set(user_script_ "${CMAKE_CURRENT_BINARY_DIR}/user-script.cmake")
+file(WRITE "${user_script_}"
+  "file(INSTALL DESTINATION \"\${CMAKE_INSTALL_PREFIX}/foo\"
+    TYPE FILE FILES \"${CMAKE_CURRENT_BINARY_DIR}/abc.txt\")")
+
+if(RunCMake_SUBTEST_SUFFIX STREQUAL "both")
+    set(CPACK_INSTALL_SCRIPT "${user_script_}")
+    set(CPACK_INSTALL_SCRIPTS "${CPACK_INSTALL_SCRIPT}")
+
+elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "singular")
+    set(CPACK_INSTALL_SCRIPT "${user_script_}")
+
+elseif(RunCMake_SUBTEST_SUFFIX STREQUAL "plural")
+    set(CPACK_INSTALL_SCRIPTS "${user_script_}")
+
+else()
+    message(FATAL_ERROR "Unexpected subtest name: ${RunCMake_SUBTEST_SUFFIX}")
+
+endif()
+
+function(run_after_include_cpack)
+  file(READ "${CPACK_OUTPUT_CONFIG_FILE}" conf_file_)
+  string(REGEX REPLACE "SET\\(CPACK_INSTALL_CMAKE_PROJECTS [^)]*\\)" "" conf_file_ "${conf_file_}")
+  file(WRITE "${CPACK_OUTPUT_CONFIG_FILE}" "${conf_file_}")
+endfunction()
diff --git a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
index f417db0..3fee79c 100644
--- a/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CTestCommandLine/RunCMakeTest.cmake
@@ -120,6 +120,20 @@
 endfunction()
 run_FailRegexFoundTest()
 
+function(run_SkipRegexFoundTest)
+  set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SkipRegexFound)
+  set(RunCMake_TEST_NO_CLEAN 1)
+  file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
+  file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+  file(WRITE "${RunCMake_TEST_BINARY_DIR}/CTestTestfile.cmake" "
+add_test(test1 \"${CMAKE_COMMAND}\" -E echo \"test1\")
+set_tests_properties(test1 PROPERTIES SKIP_REGULAR_EXPRESSION \"test1\")
+")
+
+  run_cmake_command(SkipRegexFound ${CMAKE_CTEST_COMMAND} -V)
+endfunction()
+run_SkipRegexFoundTest()
+
 function(run_SerialFailed)
   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SerialFailed)
   set(RunCMake_TEST_NO_CLEAN 1)
diff --git a/Tests/RunCMake/CTestCommandLine/SkipRegexFound-check.cmake b/Tests/RunCMake/CTestCommandLine/SkipRegexFound-check.cmake
new file mode 100644
index 0000000..1a2dfa3
--- /dev/null
+++ b/Tests/RunCMake/CTestCommandLine/SkipRegexFound-check.cmake
@@ -0,0 +1,13 @@
+set(last_test_log "${RunCMake_TEST_BINARY_DIR}/Testing/Temporary/LastTest.log")
+if(EXISTS "${last_test_log}")
+  file(READ "${last_test_log}" last_test_log_content)
+  string(REGEX REPLACE "\n+$" "" last_test_log_content "${last_test_log_content}")
+  if(NOT last_test_log_content MATCHES "
+Test Pass Reason:
+Skip regular expression found in output. Regex=[[]test1]")
+    string(REPLACE "\n" "\n  " last_test_log_content "  ${last_test_log_content}")
+    set(RunCMake_TEST_FAILED "LastTest.log does not have expected content:\n${last_test_log_content}")
+  endif()
+else()
+  set(RunCMake_TEST_FAILED "LastTest.log missing:\n ${last_test_log}")
+endif()
diff --git a/Tests/RunCMake/CommandLine/E_false-extraargs-result.txt b/Tests/RunCMake/CommandLine/E_false-extraargs-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_false-extraargs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_false-result.txt b/Tests/RunCMake/CommandLine/E_false-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_false-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index c9d3a4d..4e19871 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -26,6 +26,10 @@
 run_cmake_command(E_rename-no-arg ${CMAKE_COMMAND} -E rename)
 run_cmake_command(E_server-arg ${CMAKE_COMMAND} -E server --extra-arg)
 run_cmake_command(E_server-pipe ${CMAKE_COMMAND} -E server --pipe=)
+run_cmake_command(E_true ${CMAKE_COMMAND} -E true)
+run_cmake_command(E_true-extraargs ${CMAKE_COMMAND} -E true ignored)
+run_cmake_command(E_false ${CMAKE_COMMAND} -E false)
+run_cmake_command(E_false-extraargs ${CMAKE_COMMAND} -E false ignored)
 
 run_cmake_command(E_touch_nocreate-no-arg ${CMAKE_COMMAND} -E touch_nocreate)
 run_cmake_command(E_touch-nonexistent-dir ${CMAKE_COMMAND} -E touch "${RunCMake_BINARY_DIR}/touch-nonexistent-dir/foo")
diff --git a/Tests/RunCMake/CrosscompilingEmulator/AddCustomCommand.cmake b/Tests/RunCMake/CrosscompilingEmulator/AddCustomCommand.cmake
index c4db11b..9fcc5bc 100644
--- a/Tests/RunCMake/CrosscompilingEmulator/AddCustomCommand.cmake
+++ b/Tests/RunCMake/CrosscompilingEmulator/AddCustomCommand.cmake
@@ -26,12 +26,14 @@
 
 # DoesNotUseEmulator: The command will fail if emulator is prepended
 add_custom_command(OUTPUT output3
+  COMMAND ${CMAKE_COMMAND} -E echo generated_exe_emulator_unexpected
   COMMAND $<TARGET_FILE:generated_exe_emulator_unexpected>
   COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/output3
   DEPENDS generated_exe_emulator_unexpected)
 
 # DoesNotUseEmulator: The command will fail if emulator is prepended
 add_custom_command(OUTPUT outputImp
+  COMMAND ${CMAKE_COMMAND} -E echo generated_exe_emulator_unexpected_imported
   COMMAND generated_exe_emulator_unexpected_imported
   COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/outputImp
   )
@@ -39,6 +41,7 @@
 # UsesEmulator: The command only succeeds if the emulator is prepended
 #               to the command.
 add_custom_command(OUTPUT output4
+  COMMAND ${CMAKE_COMMAND} -E echo generated_exe_emulator_expected
   COMMAND generated_exe_emulator_expected
   COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/output4
   DEPENDS generated_exe_emulator_expected)
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index 18b9347..3b0ec6e 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
@@ -979,6 +979,11 @@
                     "_dllExtra": False,
                 },
                 {
+                    "path": "^lib/my_interface_exe\\.imp$",
+                    "_aixExtra": True,
+                    "_dllExtra": False,
+                },
+                {
                     "path": "^lib/((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?my_interface_exe\\.(dll\\.a|lib)$",
                     "_dllExtra": True,
                 },
@@ -4895,6 +4900,10 @@
         for e in expected:
             e["artifacts"] = filter_list(lambda a: not a["_dllExtra"], e["artifacts"])
 
+    if "aix" not in sys.platform:
+        for e in expected:
+            e["artifacts"] = filter_list(lambda a: not a.get("_aixExtra", False), e["artifacts"])
+
     return expected
 
 def check_targets(c, g, inSource):
diff --git a/Tests/RunCMake/GenerateExportHeader/GEH.cmake b/Tests/RunCMake/GenerateExportHeader/GEH.cmake
index b3f1c7f..ae9a84c 100644
--- a/Tests/RunCMake/GenerateExportHeader/GEH.cmake
+++ b/Tests/RunCMake/GenerateExportHeader/GEH.cmake
@@ -51,11 +51,6 @@
   set(CMAKE_CXX_STANDARD 11)
 endif()
 
-if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND
-    CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "GNU")
-  set(CMAKE_CXX_STANDARD 14)
-endif()
-
 add_subdirectory(lib_shared_and_static)
 
 if(CMAKE_SYSTEM_NAME MATCHES "AIX" AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU"
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-imported-target.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-imported-target.cmake
index 34e500a..f52776e 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-imported-target.cmake
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX-imported-target.cmake
@@ -38,7 +38,7 @@
 
 string (APPEND GENERATE_CONTENT
 "\ncheck_value (\"TARGET_FILE_PREFIX executable custom\" \"$<TARGET_FILE_PREFIX:exec2>\" \"exec2_prefix\")
-check_value (\"TARGET_LINKER_FILE_PREFIX executable linker custom\" \"$<TARGET_LINKER_FILE_PREFIX:exec2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${win_platforms}>,exec2_import_prefix,exec2_prefix>\")
+check_value (\"TARGET_LINKER_FILE_PREFIX executable linker custom\" \"$<TARGET_LINKER_FILE_PREFIX:exec2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${win_platforms};AIX>,exec2_import_prefix,exec2_prefix>\")
 check_value (\"TARGET_FILE_PREFIX shared custom\" \"$<TARGET_FILE_PREFIX:shared2>\" \"shared2_prefix\")
 check_value (\"TARGET_LINKER_FILE_PREFIX shared linker custom\" \"$<TARGET_LINKER_FILE_PREFIX:shared2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${win_platforms}>,shared2_import_prefix,shared2_prefix>\")
 check_value (\"TARGET_FILE_PREFIX static custom\" \"$<TARGET_FILE_PREFIX:static2>\" \"static2_prefix\")
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX.cmake
index 6bb1e44..bef7bbf 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX.cmake
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_FILE_PREFIX.cmake
@@ -38,7 +38,7 @@
 
 string (APPEND GENERATE_CONTENT
 "\ncheck_value (\"TARGET_FILE_PREFIX executable custom\" \"$<TARGET_FILE_PREFIX:exec2>\" \"exec2_prefix\")
-check_value (\"TARGET_LINKER_FILE_PREFIX executable linker custom\" \"$<TARGET_LINKER_FILE_PREFIX:exec2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${win_platforms}>,exec2_import_prefix,exec2_prefix>\")
+check_value (\"TARGET_LINKER_FILE_PREFIX executable linker custom\" \"$<TARGET_LINKER_FILE_PREFIX:exec2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${win_platforms};AIX>,exec2_import_prefix,exec2_prefix>\")
 check_value (\"TARGET_FILE_PREFIX shared custom\" \"$<TARGET_FILE_PREFIX:shared2>\" \"shared2_prefix\")
 check_value (\"TARGET_LINKER_FILE_PREFIX shared linker custom\" \"$<TARGET_LINKER_FILE_PREFIX:shared2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${win_platforms}>,shared2_import_prefix,shared2_prefix>\")
 check_value (\"TARGET_FILE_PREFIX static custom\" \"$<TARGET_FILE_PREFIX:static2>\" \"static2_prefix\")
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-imported-target.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-imported-target.cmake
index e1b7654..cefeb86 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-imported-target.cmake
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX-imported-target.cmake
@@ -38,7 +38,7 @@
 
 string (APPEND GENERATE_CONTENT
 "\ncheck_value (\"TARGET_FILE_SUFFIX executable custom\" \"$<TARGET_FILE_SUFFIX:exec2>\" \"exec2_suffix\")
-check_value (\"TARGET_LINKER_FILE_SUFFIX executable linker custom\" \"$<TARGET_LINKER_FILE_SUFFIX:exec2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${win_platforms}>,exec2_import_suffix,exec2_suffix>\")
+check_value (\"TARGET_LINKER_FILE_SUFFIX executable linker custom\" \"$<TARGET_LINKER_FILE_SUFFIX:exec2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${win_platforms};AIX>,exec2_import_suffix,exec2_suffix>\")
 check_value (\"TARGET_FILE_SUFFIX shared custom\" \"$<TARGET_FILE_SUFFIX:shared2>\" \"shared2_suffix\")
 check_value (\"TARGET_LINKER_FILE_SUFFIX shared linker custom\" \"$<TARGET_LINKER_FILE_SUFFIX:shared2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${win_platforms}>,shared2_import_suffix,shared2_suffix>\")
 check_value (\"TARGET_FILE_SUFFIX static custom\" \"$<TARGET_FILE_SUFFIX:static2>\" \"static2_suffix\")
diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX.cmake
index 78afecd..39e39fd 100644
--- a/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX.cmake
+++ b/Tests/RunCMake/GeneratorExpression/TARGET_FILE_SUFFIX.cmake
@@ -38,7 +38,7 @@
 
 string (APPEND GENERATE_CONTENT
 "\ncheck_value (\"TARGET_FILE_SUFFIX executable custom\" \"$<TARGET_FILE_SUFFIX:exec2>\" \"exec2_suffix\")
-check_value (\"TARGET_LINKER_FILE_SUFFIX executable linker custom\" \"$<TARGET_LINKER_FILE_SUFFIX:exec2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${win_platforms}>,exec2_import_suffix,exec2_suffix>\")
+check_value (\"TARGET_LINKER_FILE_SUFFIX executable linker custom\" \"$<TARGET_LINKER_FILE_SUFFIX:exec2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${win_platforms};AIX>,exec2_import_suffix,exec2_suffix>\")
 check_value (\"TARGET_FILE_SUFFIX shared custom\" \"$<TARGET_FILE_SUFFIX:shared2>\" \"shared2_suffix\")
 check_value (\"TARGET_LINKER_FILE_SUFFIX shared linker custom\" \"$<TARGET_LINKER_FILE_SUFFIX:shared2>\" \"$<IF:$<IN_LIST:$<PLATFORM_ID>,${win_platforms}>,shared2_import_suffix,shared2_suffix>\")
 check_value (\"TARGET_FILE_SUFFIX static custom\" \"$<TARGET_FILE_SUFFIX:static2>\" \"static2_suffix\")
diff --git a/Tests/RunCMake/RunCMake.cmake b/Tests/RunCMake/RunCMake.cmake
index e730d6e..568bdf8 100644
--- a/Tests/RunCMake/RunCMake.cmake
+++ b/Tests/RunCMake/RunCMake.cmake
@@ -144,8 +144,6 @@
     "|Error kstat returned"
     "|Hit xcodebuild bug"
     "|[^\n]*xcodebuild[^\n]*warning: file type[^\n]*is based on missing file type"
-    "|ld: 0711-224 WARNING: Duplicate symbol: .__init_aix_libgcc_cxa_atexit"
-    "|ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information"
     "|[^\n]*is a member of multiple groups"
     "|[^\n]*from Time Machine by path"
     "|[^\n]*Bullseye Testing Technology"
diff --git a/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources-stderr.txt b/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources-stderr.txt
index e332281..838992b 100644
--- a/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources-stderr.txt
+++ b/Tests/RunCMake/add_library/UNKNOWNwithOnlyObjectSources-stderr.txt
@@ -1,4 +1,4 @@
 ^CMake Error at UNKNOWNwithOnlyObjectSources.cmake:[0-9]+ \(target_sources\):
-  target_sources called with non-compilable target type
+  target_sources may only set INTERFACE properties on IMPORTED targets
 Call Stack \(most recent call first\):
   CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/find_file/FromPrefixPath.cmake b/Tests/RunCMake/find_file/FromPrefixPath.cmake
index 1bf8409..63c6a07 100644
--- a/Tests/RunCMake/find_file/FromPrefixPath.cmake
+++ b/Tests/RunCMake/find_file/FromPrefixPath.cmake
@@ -1,3 +1,4 @@
+set(ENV_PATH "$ENV{PATH}")
 set(ENV{PATH} "")
 foreach(path "/does_not_exist" "/include" "")
   unset(PrefixInPATH_File CACHE)
@@ -15,3 +16,4 @@
   message(STATUS "PrefixInPATH_File='${PrefixInPATH_File}'")
 endforeach()
 set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH ON)
+set(ENV{PATH} "${ENV_PATH}")
diff --git a/Tests/RunCMake/find_package/FromPATHEnv-stdout.txt b/Tests/RunCMake/find_package/FromPATHEnv-stdout.txt
new file mode 100644
index 0000000..2ead349
--- /dev/null
+++ b/Tests/RunCMake/find_package/FromPATHEnv-stdout.txt
@@ -0,0 +1,9 @@
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='1'
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='0'
diff --git a/Tests/RunCMake/find_package/FromPATHEnv.cmake b/Tests/RunCMake/find_package/FromPATHEnv.cmake
new file mode 100644
index 0000000..4822b13
--- /dev/null
+++ b/Tests/RunCMake/find_package/FromPATHEnv.cmake
@@ -0,0 +1,27 @@
+set(ENV_PATH "$ENV{PATH}")
+foreach(path "/does_not_exist" "/PackageRoot" "")
+  unset(Resolved_FOUND CACHE)
+  set(Resolved_DIR "")
+  set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}${path}")
+  find_package(Resolved QUIET)
+  message(STATUS "Resolved_FOUND='${Resolved_FOUND}'")
+endforeach()
+
+set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH OFF)
+foreach(path "/does_not_exist" "/PackageRoot" "")
+  unset(Resolved_FOUND CACHE)
+  set(Resolved_DIR "")
+  set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}${path}")
+  find_package(Resolved QUIET)
+  message(STATUS "Resolved_FOUND='${Resolved_FOUND}'")
+endforeach()
+
+set(CMAKE_FIND_USE_SYSTEM_ENVIRONMENT_PATH ON)
+foreach(path "/does_not_exist" "/PackageRoot" "")
+  unset(Resolved_FOUND CACHE)
+  set(Resolved_DIR "")
+  set(ENV{PATH} "${CMAKE_CURRENT_SOURCE_DIR}${path}")
+  find_package(Resolved NO_SYSTEM_ENVIRONMENT_PATH QUIET)
+  message(STATUS "Resolved_FOUND='${Resolved_FOUND}'")
+endforeach()
+set(ENV{PATH} "${ENV_PATH}")
diff --git a/Tests/RunCMake/find_package/FromPrefixPath-stdout.txt b/Tests/RunCMake/find_package/FromPrefixPath-stdout.txt
new file mode 100644
index 0000000..2ead349
--- /dev/null
+++ b/Tests/RunCMake/find_package/FromPrefixPath-stdout.txt
@@ -0,0 +1,9 @@
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='1'
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='0'
+-- Resolved_FOUND='0'
diff --git a/Tests/RunCMake/find_package/FromPrefixPath.cmake b/Tests/RunCMake/find_package/FromPrefixPath.cmake
new file mode 100644
index 0000000..be853c1
--- /dev/null
+++ b/Tests/RunCMake/find_package/FromPrefixPath.cmake
@@ -0,0 +1,29 @@
+set(ENV_PATH "$ENV{PATH}")
+set(ENV{PATH} "")
+foreach(path "/does_not_exist" "/PackageRoot" "")
+  unset(Resolved_FOUND CACHE)
+  set(Resolved_DIR "")
+  set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}${path}")
+  find_package(Resolved QUIET)
+  message(STATUS "Resolved_FOUND='${Resolved_FOUND}'")
+endforeach()
+
+set(CMAKE_FIND_USE_CMAKE_PATH OFF)
+set(CMAKE_PREFIX_PATH )
+foreach(path "/does_not_exist" "/PackageRoot" "")
+  unset(Resolved_FOUND CACHE)
+  set(Resolved_DIR "")
+  set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}${path}")
+  find_package(Resolved QUIET)
+  message(STATUS "Resolved_FOUND='${Resolved_FOUND}'")
+endforeach()
+
+set(CMAKE_FIND_USE_CMAKE_PATH ON)
+foreach(path "/does_not_exist" "/PackageRoot" "")
+  unset(Resolved_FOUND CACHE)
+  set(Resolved_DIR "")
+  set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_SOURCE_DIR}${path}")
+  find_package(Resolved NO_CMAKE_PATH QUIET)
+  message(STATUS "Resolved_FOUND='${Resolved_FOUND}'")
+endforeach()
+set(ENV{PATH} "${ENV_PATH}")
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
index 066523e..208f83c 100644
--- a/Tests/RunCMake/find_package/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -3,6 +3,8 @@
 run_cmake(CMP0074-WARN)
 run_cmake(CMP0074-OLD)
 run_cmake(ComponentRequiredAndOptional)
+run_cmake(FromPATHEnv)
+run_cmake(FromPrefixPath)
 run_cmake(MissingNormal)
 run_cmake(MissingNormalRequired)
 run_cmake(MissingNormalVersion)
diff --git a/Tests/RunCMake/find_program/RelAndAbsPath.cmake b/Tests/RunCMake/find_program/RelAndAbsPath.cmake
index 3c60a20..6b61980 100644
--- a/Tests/RunCMake/find_program/RelAndAbsPath.cmake
+++ b/Tests/RunCMake/find_program/RelAndAbsPath.cmake
@@ -10,7 +10,6 @@
 
 strip_windows_path_prefix("${CMAKE_CURRENT_SOURCE_DIR}" srcdir)
 
-file(MAKE_DIRECTORY "tmp${srcdir}")
 configure_file(testCWD "tmp${srcdir}/testNoSuchFile" COPYONLY)
 
 find_program(PROG_ABS
diff --git a/Tests/RunCMake/math/MATH-InvalidExpression-stderr.txt b/Tests/RunCMake/math/MATH-InvalidExpression-stderr.txt
index 9e73ed5..22226f2 100644
--- a/Tests/RunCMake/math/MATH-InvalidExpression-stderr.txt
+++ b/Tests/RunCMake/math/MATH-InvalidExpression-stderr.txt
@@ -1,5 +1,5 @@
 ^CMake Error at MATH-InvalidExpression.cmake:1 \(math\):
-  math cannot parse the expression: "INVALID": syntax error, unexpected \$end,
-  expecting exp_PLUS or exp_MINUS or exp_OPENPARENT or exp_NUMBER \(7\).
+  math cannot parse the expression: "INVALID": syntax error, unexpected \$end
+  \(7\).
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/message/RunCMakeTest.cmake b/Tests/RunCMake/message/RunCMakeTest.cmake
index cecfc7f..3c7e51c 100644
--- a/Tests/RunCMake/message/RunCMakeTest.cmake
+++ b/Tests/RunCMake/message/RunCMakeTest.cmake
@@ -52,3 +52,12 @@
     message-loglevel-trace
     ${CMAKE_COMMAND} --loglevel=trace -P ${RunCMake_SOURCE_DIR}/message-all-loglevels.cmake
   )
+
+run_cmake_command(
+    message-indent
+    ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/message-indent.cmake
+  )
+run_cmake_command(
+    message-indent-multiline
+    ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/message-indent-multiline.cmake
+  )
diff --git a/Tests/RunCMake/message/message-indent-multiline-stderr.txt b/Tests/RunCMake/message/message-indent-multiline-stderr.txt
new file mode 100644
index 0000000..5853a31
--- /dev/null
+++ b/Tests/RunCMake/message/message-indent-multiline-stderr.txt
@@ -0,0 +1,3 @@
+ >This is
+ >the multiline
+ >message
diff --git a/Tests/RunCMake/message/message-indent-multiline-stdout.txt b/Tests/RunCMake/message/message-indent-multiline-stdout.txt
new file mode 100644
index 0000000..ae0c72e
--- /dev/null
+++ b/Tests/RunCMake/message/message-indent-multiline-stdout.txt
@@ -0,0 +1,8 @@
+--  >This is
+ >the multiline
+ >message
+ >
+ >
+--  >This is
+ >the multiline
+ >message
diff --git a/Tests/RunCMake/message/message-indent-multiline.cmake b/Tests/RunCMake/message/message-indent-multiline.cmake
new file mode 100644
index 0000000..0f789bf
--- /dev/null
+++ b/Tests/RunCMake/message/message-indent-multiline.cmake
@@ -0,0 +1,13 @@
+# NOTE Use non-space indent string, to check indentation
+# of line endings and "empty" lines.
+# ALERT Do not put any space characters after the non-space!
+list(APPEND CMAKE_MESSAGE_INDENT " >")
+set(msg [[This is
+the multiline
+message]]) # No `\n` at the end!
+# NOTE Two empty lines after the text
+message(STATUS "${msg}\n\n")
+message(STATUS "${msg}")
+# This is just to make sure NOTICE messages are also get indented:
+# https://gitlab.kitware.com/cmake/cmake/issues/19418#note_588011
+message(NOTICE "${msg}")
diff --git a/Tests/RunCMake/message/message-indent-stdout.txt b/Tests/RunCMake/message/message-indent-stdout.txt
new file mode 100644
index 0000000..b2c3c60
--- /dev/null
+++ b/Tests/RunCMake/message/message-indent-stdout.txt
@@ -0,0 +1,13 @@
+-- COUNTING:
+--    COUNTING_ENGLISH:
+--       one
+--       two
+--       three
+--       four
+--       five
+--    COUNTING_BAHASA:
+--       satu
+--       dua
+--       tiga
+--       empat
+--       lima
diff --git a/Tests/RunCMake/message/message-indent.cmake b/Tests/RunCMake/message/message-indent.cmake
new file mode 100644
index 0000000..c07ff45
--- /dev/null
+++ b/Tests/RunCMake/message/message-indent.cmake
@@ -0,0 +1,19 @@
+function(debug_list LIST_VAR)
+  message(STATUS "${LIST_VAR}:")
+  list(APPEND CMAKE_MESSAGE_INDENT "   ")
+  foreach(_item IN LISTS ${LIST_VAR})
+    list(LENGTH ${_item} _item_len)
+    if(_item_len GREATER 1)
+      debug_list(${_item})
+    else()
+      message(STATUS "${_item}")
+    endif()
+  endforeach()
+endfunction()
+
+list(APPEND COUNTING_ENGLISH one two three four five)
+list(APPEND COUNTING_BAHASA satu dua tiga empat lima)
+
+list(APPEND COUNTING COUNTING_ENGLISH COUNTING_BAHASA)
+
+debug_list(COUNTING)
diff --git a/Tests/RunCMake/project/CMP0048-NEW.cmake b/Tests/RunCMake/project/CMP0048-NEW.cmake
index 7e16b70..b6e80ac 100644
--- a/Tests/RunCMake/project/CMP0048-NEW.cmake
+++ b/Tests/RunCMake/project/CMP0048-NEW.cmake
@@ -1,9 +1,4 @@
-macro(print_versions name)
-  foreach(v "" _MAJOR _MINOR _PATCH _TWEAK)
-    message(STATUS "PROJECT_VERSION${v}='${PROJECT_VERSION${v}}'")
-    message(STATUS "${name}_VERSION${v}='${${name}_VERSION${v}}'")
-  endforeach()
-endmacro()
+include(PrintVersions.cmake)
 
 cmake_policy(SET CMP0048 NEW)
 
diff --git a/Tests/RunCMake/project/CMP0096-NEW-stdout.txt b/Tests/RunCMake/project/CMP0096-NEW-stdout.txt
new file mode 100644
index 0000000..f6b999a
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0096-NEW-stdout.txt
@@ -0,0 +1,30 @@
+-- PROJECT_VERSION='2019.07.06'
+-- DateVersion_VERSION='2019.07.06'
+-- PROJECT_VERSION_MAJOR='2019'
+-- DateVersion_VERSION_MAJOR='2019'
+-- PROJECT_VERSION_MINOR='07'
+-- DateVersion_VERSION_MINOR='07'
+-- PROJECT_VERSION_PATCH='06'
+-- DateVersion_VERSION_PATCH='06'
+-- PROJECT_VERSION_TWEAK=''
+-- DateVersion_VERSION_TWEAK=''
+-- PROJECT_VERSION='4294967297'
+-- LongVersion_VERSION='4294967297'
+-- PROJECT_VERSION_MAJOR='4294967297'
+-- LongVersion_VERSION_MAJOR='4294967297'
+-- PROJECT_VERSION_MINOR=''
+-- LongVersion_VERSION_MINOR=''
+-- PROJECT_VERSION_PATCH=''
+-- LongVersion_VERSION_PATCH=''
+-- PROJECT_VERSION_TWEAK=''
+-- LongVersion_VERSION_TWEAK=''
+-- PROJECT_VERSION='0009999999999.0009999999999.0009999999999.0009999999999'
+-- VeryLongVersion_VERSION='0009999999999.0009999999999.0009999999999.0009999999999'
+-- PROJECT_VERSION_MAJOR='0009999999999'
+-- VeryLongVersion_VERSION_MAJOR='0009999999999'
+-- PROJECT_VERSION_MINOR='0009999999999'
+-- VeryLongVersion_VERSION_MINOR='0009999999999'
+-- PROJECT_VERSION_PATCH='0009999999999'
+-- VeryLongVersion_VERSION_PATCH='0009999999999'
+-- PROJECT_VERSION_TWEAK='0009999999999'
+-- VeryLongVersion_VERSION_TWEAK='0009999999999'
diff --git a/Tests/RunCMake/project/CMP0096-NEW.cmake b/Tests/RunCMake/project/CMP0096-NEW.cmake
new file mode 100644
index 0000000..e2cdd20
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0096-NEW.cmake
@@ -0,0 +1,6 @@
+cmake_policy(SET CMP0048 NEW)
+cmake_policy(SET CMP0096 NEW)
+include(CMP0096-common.cmake)
+
+project(VeryLongVersion VERSION 0009999999999.0009999999999.0009999999999.0009999999999 LANGUAGES NONE)
+print_versions(VeryLongVersion)
diff --git a/Tests/RunCMake/project/CMP0096-OLD-stdout.txt b/Tests/RunCMake/project/CMP0096-OLD-stdout.txt
new file mode 100644
index 0000000..6a945ce
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0096-OLD-stdout.txt
@@ -0,0 +1,20 @@
+-- PROJECT_VERSION='2019.7.6'
+-- DateVersion_VERSION='2019.7.6'
+-- PROJECT_VERSION_MAJOR='2019'
+-- DateVersion_VERSION_MAJOR='2019'
+-- PROJECT_VERSION_MINOR='7'
+-- DateVersion_VERSION_MINOR='7'
+-- PROJECT_VERSION_PATCH='6'
+-- DateVersion_VERSION_PATCH='6'
+-- PROJECT_VERSION_TWEAK=''
+-- DateVersion_VERSION_TWEAK=''
+-- PROJECT_VERSION='(1|4294967295)'
+-- LongVersion_VERSION='(1|4294967295)'
+-- PROJECT_VERSION_MAJOR='(1|4294967295)'
+-- LongVersion_VERSION_MAJOR='(1|4294967295)'
+-- PROJECT_VERSION_MINOR=''
+-- LongVersion_VERSION_MINOR=''
+-- PROJECT_VERSION_PATCH=''
+-- LongVersion_VERSION_PATCH=''
+-- PROJECT_VERSION_TWEAK=''
+-- LongVersion_VERSION_TWEAK=''
diff --git a/Tests/RunCMake/project/CMP0096-OLD.cmake b/Tests/RunCMake/project/CMP0096-OLD.cmake
new file mode 100644
index 0000000..25a3b19
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0096-OLD.cmake
@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0048 NEW)
+cmake_policy(SET CMP0096 OLD)
+include(CMP0096-common.cmake)
diff --git a/Tests/RunCMake/project/CMP0096-WARN-stdout.txt b/Tests/RunCMake/project/CMP0096-WARN-stdout.txt
new file mode 100644
index 0000000..6a945ce
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0096-WARN-stdout.txt
@@ -0,0 +1,20 @@
+-- PROJECT_VERSION='2019.7.6'
+-- DateVersion_VERSION='2019.7.6'
+-- PROJECT_VERSION_MAJOR='2019'
+-- DateVersion_VERSION_MAJOR='2019'
+-- PROJECT_VERSION_MINOR='7'
+-- DateVersion_VERSION_MINOR='7'
+-- PROJECT_VERSION_PATCH='6'
+-- DateVersion_VERSION_PATCH='6'
+-- PROJECT_VERSION_TWEAK=''
+-- DateVersion_VERSION_TWEAK=''
+-- PROJECT_VERSION='(1|4294967295)'
+-- LongVersion_VERSION='(1|4294967295)'
+-- PROJECT_VERSION_MAJOR='(1|4294967295)'
+-- LongVersion_VERSION_MAJOR='(1|4294967295)'
+-- PROJECT_VERSION_MINOR=''
+-- LongVersion_VERSION_MINOR=''
+-- PROJECT_VERSION_PATCH=''
+-- LongVersion_VERSION_PATCH=''
+-- PROJECT_VERSION_TWEAK=''
+-- LongVersion_VERSION_TWEAK=''
diff --git a/Tests/RunCMake/project/CMP0096-WARN.cmake b/Tests/RunCMake/project/CMP0096-WARN.cmake
new file mode 100644
index 0000000..7fe0861
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0096-WARN.cmake
@@ -0,0 +1,3 @@
+cmake_policy(SET CMP0048 NEW)
+
+include(CMP0096-common.cmake)
diff --git a/Tests/RunCMake/project/CMP0096-common.cmake b/Tests/RunCMake/project/CMP0096-common.cmake
new file mode 100644
index 0000000..8d26d30
--- /dev/null
+++ b/Tests/RunCMake/project/CMP0096-common.cmake
@@ -0,0 +1,9 @@
+include(PrintVersions.cmake)
+
+# Test leading zeros motivating this policy.
+project(DateVersion VERSION 2019.07.06 LANGUAGES NONE)
+print_versions(DateVersion)
+
+# Overflow version component in OLD behavior.
+project(LongVersion VERSION 4294967297 #[[ uint32_max + 2 ]] LANGUAGES NONE)
+print_versions(LongVersion)
diff --git a/Tests/RunCMake/project/PrintVersions.cmake b/Tests/RunCMake/project/PrintVersions.cmake
new file mode 100644
index 0000000..ce1b25d
--- /dev/null
+++ b/Tests/RunCMake/project/PrintVersions.cmake
@@ -0,0 +1,6 @@
+macro(print_versions name)
+  foreach(v "" _MAJOR _MINOR _PATCH _TWEAK)
+    message(STATUS "PROJECT_VERSION${v}='${PROJECT_VERSION${v}}'")
+    message(STATUS "${name}_VERSION${v}='${${name}_VERSION${v}}'")
+  endforeach()
+endmacro()
diff --git a/Tests/RunCMake/project/RunCMakeTest.cmake b/Tests/RunCMake/project/RunCMakeTest.cmake
index 3a8ad4b..8f43a51 100644
--- a/Tests/RunCMake/project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/project/RunCMakeTest.cmake
@@ -27,3 +27,7 @@
 run_cmake(CMP0048-OLD-VERSION)
 run_cmake(CMP0048-WARN)
 run_cmake(CMP0048-NEW)
+
+run_cmake(CMP0096-WARN)
+run_cmake(CMP0096-OLD)
+run_cmake(CMP0096-NEW)
diff --git a/Tests/RunCMake/target_compile_definitions/RunCMakeTest.cmake b/Tests/RunCMake/target_compile_definitions/RunCMakeTest.cmake
index b67c598..a419cc9 100644
--- a/Tests/RunCMake/target_compile_definitions/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_compile_definitions/RunCMakeTest.cmake
@@ -1,3 +1,4 @@
 include(RunCMake)
 
 run_cmake(empty_keyword_args)
+run_cmake(unknown_imported_target)
diff --git a/Tests/RunCMake/target_compile_definitions/unknown_imported_target.cmake b/Tests/RunCMake/target_compile_definitions/unknown_imported_target.cmake
new file mode 100644
index 0000000..4ae1c0d
--- /dev/null
+++ b/Tests/RunCMake/target_compile_definitions/unknown_imported_target.cmake
@@ -0,0 +1,11 @@
+# Test that target_compile_definitions works on UNKNOWN IMPORTED target
+add_library(imported UNKNOWN IMPORTED)
+target_compile_definitions(imported INTERFACE FOO)
+
+get_target_property(IMPORTED_INTERFACE_CDS imported INTERFACE_COMPILE_DEFINITIONS)
+
+if (NOT FOO IN_LIST IMPORTED_INTERFACE_CDS)
+  message(
+    FATAL_ERROR "FOO should be in INTERFACE_COMPILE_DEFINITIONS.\n"
+    "Actual INTERFACE_COMPILE_DEFINITIONS: " ${IMPORTED_INTERFACE_CDS})
+endif()
diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp
index 4e00214..9fff442 100644
--- a/Utilities/IWYU/mapping.imp
+++ b/Utilities/IWYU/mapping.imp
@@ -51,7 +51,9 @@
   { symbol: [ "std::allocator_traits<std::allocator<cmOrderDirectories::ConflictList> >::value_type", private, "<vector>", public ] },
   { symbol: [ "std::allocator_traits<std::allocator<cmStateSnapshot> >::value_type", private, "<vector>", public ] },
   { symbol: [ "std::allocator_traits<std::allocator<std::basic_string<char> > >::value_type", private, "<vector>", public ] },
+  { symbol: [ "std::allocator_traits<std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::value_type", private, "<vector>", public ] },
   { symbol: [ "std::allocator_traits<std::allocator<std::vector<std::basic_string<char>, std::allocator<std::basic_string<char> > > > >::value_type", private, "<vector>", public ] },
+  { symbol: [ "std::allocator_traits<std::allocator<std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > > >::value_type", private, "<vector>", public ] },
   { symbol: [ "std::allocator_traits<std::allocator<uv_stdio_container_s> >::value_type", private, "<vector>", public ] },
 
   # TODO: enable this block and remove some <utility> includes?
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index c5b2bfe..e4e6e05 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -105,7 +105,6 @@
     # Workaround sphinx configurability:
     # https://bitbucket.org/birkenfeld/sphinx/issue/1448/make-qthelp-more-configurable
     COMMAND ${CMAKE_COMMAND} "-DQTHELP_DIR=${CMAKE_CURRENT_BINARY_DIR}/qthelp/"
-      "-DCMake_VERSION=${CMake_VERSION_MAJOR}${CMake_VERSION_MINOR}${CMake_VERSION_PATCH}"
       -P "${CMAKE_CURRENT_SOURCE_DIR}/fixup_qthelp_names.cmake"
 
     # Create proper identifiers. Workaround for
@@ -216,7 +215,7 @@
 
 if(SPHINX_QTHELP)
   CMake_OPTIONAL_COMPONENT(sphinx-qthelp)
-  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qthelp/CMake-${CMake_VERSION_MAJOR}${CMake_VERSION_MINOR}${CMake_VERSION_PATCH}.qch
+  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/qthelp/CMake.qch
           DESTINATION ${CMAKE_DOC_DIR} ${COMPONENT}
           )
 endif()
diff --git a/Utilities/Sphinx/conf.py.in b/Utilities/Sphinx/conf.py.in
index 70ba080..e50c4f9 100644
--- a/Utilities/Sphinx/conf.py.in
+++ b/Utilities/Sphinx/conf.py.in
@@ -82,4 +82,4 @@
 # Not supported yet by sphinx:
 # https://bitbucket.org/birkenfeld/sphinx/issue/1448/make-qthelp-more-configurable
 # qthelp_namespace = "org.cmake"
-# qthelp_qch_name = "CMake-300.qch"
+# qthelp_qch_name = "CMake.qch"
diff --git a/Utilities/Sphinx/fixup_qthelp_names.cmake b/Utilities/Sphinx/fixup_qthelp_names.cmake
index e35ef25..179e846 100644
--- a/Utilities/Sphinx/fixup_qthelp_names.cmake
+++ b/Utilities/Sphinx/fixup_qthelp_names.cmake
@@ -10,15 +10,6 @@
   QHCP_CONTENT "${QHCP_CONTENT}"
 )
 
-string(REPLACE
-  "<output>CMake.qch" "<output>CMake-${CMake_VERSION}.qch"
-  QHCP_CONTENT "${QHCP_CONTENT}"
-)
-string(REPLACE
-  "<file>CMake.qch" "<file>CMake-${CMake_VERSION}.qch"
-  QHCP_CONTENT "${QHCP_CONTENT}"
-)
-
 file(WRITE "${QTHELP_DIR}/CMake.qhcp" "${QHCP_CONTENT}")
 
 
diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index 37522fc..bc8a7dc 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -449,7 +449,12 @@
 endif()
 
 if(CMAKE_USE_OPENSSL)
-  find_package(OpenSSL REQUIRED)
+  find_package(OpenSSL)
+  if(NOT OpenSSL_FOUND)
+    message(FATAL_ERROR
+      "Could not find OpenSSL. Install an OpenSSL development package or "
+      "configure CMake with -DCMAKE_USE_OPENSSL=OFF to build without OpenSSL.")
+  endif()
   set(SSL_ENABLED ON)
   set(USE_OPENSSL ON)
   set(HAVE_LIBCRYPTO ON)
diff --git a/bootstrap b/bootstrap
index c2194fe..7d9631c 100755
--- a/bootstrap
+++ b/bootstrap
@@ -440,7 +440,6 @@
   cmTimestamp \
   cmTryCompileCommand \
   cmTryRunCommand \
-  cmUnexpectedCommand \
   cmUnsetCommand \
   cmUVHandlePtr \
   cmUVProcessChain \
@@ -1125,6 +1124,25 @@
 #error "SunPro <= 5.13 mode not supported due to bug in move semantics."
 #endif
 
+#if __cplusplus > 201103L
+#include <iterator>
+int check_cxx14()
+{
+  int a[] = { 0, 1, 2 };
+  auto ai = std::cbegin(a);
+
+  int b[] = { 2, 1, 0 };
+  auto bi = std::cend(b);
+
+  return *ai + *(bi - 1);
+}
+#else
+int check_cxx14()
+{
+  return 0;
+}
+#endif
+
 class Class
 {
 public:
@@ -1135,7 +1153,7 @@
 int main()
 {
   auto const c = std::unique_ptr<Class>(new Class);
-  std::cout << c->Get() << std::endl;
+  std::cout << c->Get() << check_cxx14() << std::endl;
   return 0;
 }
 ' > "${TMPFILE}.cxx"