[libc++] Move the GDB pretty printer tests to the DSL

Also, enable them whenever we detect that gdb is available. Previously,
these tests would basically never run because they relied on a CMake
configuration option that defaulted to OFF.

Differential Revision: https://reviews.llvm.org/D91434

GitOrigin-RevId: 7ad8e19958b271b9369e6b9d8d76f2f9f1beeb90
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8e0864c..840bc5d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -128,7 +128,6 @@
    to provide compile-time errors when using features unavailable on some version of
    the shared library they shipped should turn this on and see `include/__availability`
    for more details." OFF)
-option(LIBCXX_TEST_GDB_PRETTY_PRINTERS "Test gdb pretty printers." OFF)
 set(LIBCXX_TEST_CONFIG "${CMAKE_CURRENT_SOURCE_DIR}/test/configs/legacy.cfg.in" CACHE STRING
     "The Lit testing configuration to use when running the tests.")
 set(LIBCXX_TEST_PARAMS "" CACHE STRING
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 4d9f2e5..e9a8869 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -91,18 +91,6 @@
   message(FATAL_ERROR "Expected LIBCXX_TEST_DEPS to be defined")
 endif()
 
-# Turn this on by default when the pretty printers are python3
-# compatible.
-if(LIBCXX_TEST_GDB_PRETTY_PRINTERS)
-  find_program(LIBCXX_GDB gdb)
-  if (LIBCXX_GDB)
-    set(LIBCXX_GDB "${LIBCXX_GDB}")
-    message(STATUS "gdb found: ${LIBCXX_GDB}")
-  else()
-    message(STATUS "gdb not found. Disabling dependent tests.")
-  endif()
-endif()
-
 if (LIBCXX_INCLUDE_TESTS)
   include(AddLLVM) # for configure_lit_site_cfg and add_lit_target
 
diff --git a/test/configs/legacy.cfg.in b/test/configs/legacy.cfg.in
index f0a4e8a..c8c6855 100644
--- a/test/configs/legacy.cfg.in
+++ b/test/configs/legacy.cfg.in
@@ -38,7 +38,6 @@
 config.cxx_ext_threads          = @LIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY@
 config.pstl_src_root            = "@ParallelSTL_SOURCE_DIR@" if @LIBCXX_ENABLE_PARALLEL_ALGORITHMS@ else None
 config.pstl_obj_root            = "@ParallelSTL_BINARY_DIR@" if @LIBCXX_ENABLE_PARALLEL_ALGORITHMS@ else None
-config.libcxx_gdb               = "@LIBCXX_GDB@"
 
 # Code signing
 config.llvm_codesign_identity   = "@LLVM_CODESIGNING_IDENTITY@"
diff --git a/test/pretty_printers/gdb_pretty_printer_test.py b/test/libcxx/gdb/gdb_pretty_printer_test.py
similarity index 100%
rename from test/pretty_printers/gdb_pretty_printer_test.py
rename to test/libcxx/gdb/gdb_pretty_printer_test.py
diff --git a/test/pretty_printers/gdb_pretty_printer_test.sh.cpp b/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
similarity index 97%
rename from test/pretty_printers/gdb_pretty_printer_test.sh.cpp
rename to test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
index 540db56..fed6a16 100644
--- a/test/pretty_printers/gdb_pretty_printer_test.sh.cpp
+++ b/test/libcxx/gdb/gdb_pretty_printer_test.sh.cpp
@@ -6,11 +6,14 @@
 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 //
 //===----------------------------------------------------------------------===//
-// REQUIRES: libcxx_gdb
-//
+
+// REQUIRES: host-has-gdb
+// UNSUPPORTED: libcpp-has-no-localization
+// UNSUPPORTED: c++03
+
 // RUN: %{cxx} %{flags} %s -o %t.exe %{compile_flags} -g %{link_flags}
 // Ensure locale-independence for unicode tests.
-// RUN: %{libcxx_gdb} -nx -batch -iex "set autoload off" -ex "source %S/../../utils/gdb/libcxx/printers.py" -ex "python register_libcxx_printer_loader()" -ex "source %S/gdb_pretty_printer_test.py" %t.exe
+// RUN: %{gdb} -nx -batch -iex "set autoload off" -ex "source %S/../../../utils/gdb/libcxx/printers.py" -ex "python register_libcxx_printer_loader()" -ex "source %S/gdb_pretty_printer_test.py" %t.exe
 
 #include <bitset>
 #include <deque>
@@ -60,15 +63,15 @@
 #else
 #define OPT_NONE __attribute__((optnone))
 #endif
-void StopForDebugger(void *value, void *check) OPT_NONE;
-void StopForDebugger(void *value, void *check)  {}
+void StopForDebugger(void *, void *) OPT_NONE;
+void StopForDebugger(void *, void *)  {}
 
 
 // Prevents the compiler optimizing away the parameter in the caller function.
 template <typename Type>
-void MarkAsLive(Type &&t) OPT_NONE;
+void MarkAsLive(Type &&) OPT_NONE;
 template <typename Type>
-void MarkAsLive(Type &&t) {}
+void MarkAsLive(Type &&) {}
 
 // In all of the Compare(Expression)PrettyPrintTo(Regex/Chars) functions below,
 // the python script sets a breakpoint just before the call to StopForDebugger,
@@ -643,7 +646,7 @@
       test1, "std::fpos with stream offset:5 with state: {count:0 value:0}");
 }
 
-int main(int argc, char* argv[]) {
+int main(int, char**) {
   framework_self_test();
 
   string_test();
diff --git a/utils/libcxx/test/config.py b/utils/libcxx/test/config.py
index ca0385a..a10d439 100644
--- a/utils/libcxx/test/config.py
+++ b/utils/libcxx/test/config.py
@@ -247,11 +247,6 @@
                 # using this feature. (Also see llvm.org/PR32730)
                 self.config.available_features.add('LIBCXX-WINDOWS-FIXME')
 
-        libcxx_gdb = self.get_lit_conf('libcxx_gdb')
-        if libcxx_gdb and 'NOTFOUND' not in libcxx_gdb:
-            self.config.available_features.add('libcxx_gdb')
-            self.cxx.libcxx_gdb = libcxx_gdb
-
         target_triple = getattr(self.config, 'target_triple', None)
         if target_triple:
             if re.match(r'^x86_64.*-apple', target_triple):
@@ -599,8 +594,6 @@
             '--env {}'.format(env_vars)
         ]
         sub.append(('%{exec}', '{} {} -- '.format(self.executor, ' '.join(exec_args))))
-        if self.get_lit_conf('libcxx_gdb'):
-            sub.append(('%{libcxx_gdb}', self.get_lit_conf('libcxx_gdb')))
 
     def configure_triple(self):
         # Get or infer the target triple.
diff --git a/utils/libcxx/test/dsl.py b/utils/libcxx/test/dsl.py
index 93722a1..012d13a 100644
--- a/utils/libcxx/test/dsl.py
+++ b/utils/libcxx/test/dsl.py
@@ -350,6 +350,26 @@
     return 'add {} to %{{compile_flags}}'.format(self._getFlag(config))
 
 
+class AddSubstitution(ConfigAction):
+  """
+  This action adds the given substitution to the Lit configuration.
+
+  The substitution can be a string or a callable, in which case it is called
+  with the configuration to produce the actual substitution (as a string).
+  """
+  def __init__(self, key, substitution):
+    self._key = key
+    self._getSub = lambda config: substitution(config) if callable(substitution) else substitution
+
+  def applyTo(self, config):
+    key = self._key
+    sub = self._getSub(config)
+    config.substitutions.append((key, sub))
+
+  def pretty(self, config, litParams):
+    return 'add substitution {} = {}'.format(self._key, self._getSub(config))
+
+
 class Feature(object):
   """
   Represents a Lit available feature that is enabled whenever it is supported.
diff --git a/utils/libcxx/test/features.py b/utils/libcxx/test/features.py
index 51f9296..f78db66 100644
--- a/utils/libcxx/test/features.py
+++ b/utils/libcxx/test/features.py
@@ -8,6 +8,7 @@
 
 from libcxx.test.dsl import *
 import re
+import shutil
 import sys
 
 _isClang      = lambda cfg: '__clang__' in compilerMacros(cfg) and '__apple_build_version__' not in compilerMacros(cfg)
@@ -131,6 +132,15 @@
 ]
 
 
+# Detect whether GDB is on the system, and if so add a substitution to access it.
+DEFAULT_FEATURES += [
+  Feature(name='host-has-gdb',
+    when=lambda cfg: shutil.which('gdb') is not None,
+    actions=[AddSubstitution('%{gdb}', lambda cfg: shutil.which('gdb'))]
+  )
+]
+
+
 # When vendor-specific availability annotations are enabled, add Lit features
 # with various forms of the target triple to make it easier to write XFAIL or
 # UNSUPPORTED markup for tests that are known to fail on a particular triple.