astrelni created this revision.
astrelni added reviewers: alexfh, hokein, aaron.ballman, JonasToth, EricWF.
astrelni added a project: clang-tools-extra.
Herald added subscribers: llvm-commits, cfe-commits, xazax.hun, mgorny.
Herald added projects: clang, LLVM.

Introduce a new check to upgrade user code based on API changes in Googletest.

The check finds uses of old Googletest APIs with "case" in their name and 
replaces them with the new APIs named with "suite".


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D62977

Files:
  clang-tools-extra/clang-tidy/google/CMakeLists.txt
  clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp
  clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp
  clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/google-upgrade-googletest-case.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/Inputs/gtest/gtest-typed-test.h
  clang-tools-extra/test/clang-tidy/Inputs/gtest/gtest.h
  clang-tools-extra/test/clang-tidy/google-upgrade-googletest-case.cpp
  llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/google/BUILD.gn

Index: llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/google/BUILD.gn
===================================================================
--- llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/google/BUILD.gn
+++ llvm/utils/gn/secondary/clang-tools-extra/clang-tidy/google/BUILD.gn
@@ -28,6 +28,7 @@
     "OverloadedUnaryAndCheck.cpp",
     "TodoCommentCheck.cpp",
     "UnnamedNamespaceInHeaderCheck.cpp",
+    "UpgradeGoogletestCaseCheck.cpp",
     "UsingNamespaceDirectiveCheck.cpp",
   ]
 }
Index: clang-tools-extra/test/clang-tidy/google-upgrade-googletest-case.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/google-upgrade-googletest-case.cpp
@@ -0,0 +1,991 @@
+// RUN: %check_clang_tidy %s google-upgrade-googletest-case %t -- -- -I%S/Inputs
+
+#include "gtest/gtest.h"
+
+// ----------------------------------------------------------------------------
+// Macros
+
+TYPED_TEST_CASE(FooTest, FooTypes);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: TYPED_TEST_SUITE(FooTest, FooTypes);
+TYPED_TEST_CASE_P(FooTest);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: TYPED_TEST_SUITE_P(FooTest);
+REGISTER_TYPED_TEST_CASE_P(FooTest, FooTestName);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: REGISTER_TYPED_TEST_SUITE_P(FooTest, FooTestName);
+INSTANTIATE_TYPED_TEST_CASE_P(FooPrefix, FooTest, FooTypes);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: INSTANTIATE_TYPED_TEST_SUITE_P(FooPrefix, FooTest, FooTypes);
+
+#ifdef TYPED_TEST_CASE
+// CHECK-MESSAGES: [[@LINE-1]]:2: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+#undef TYPED_TEST_CASE
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+#define TYPED_TEST_CASE TYPED_TEST_SUITE
+#endif
+
+#ifdef TYPED_TEST_CASE_P
+// CHECK-MESSAGES: [[@LINE-1]]:2: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+#undef TYPED_TEST_CASE_P
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+#define TYPED_TEST_CASE_P TYPED_TEST_SUITE_P
+#endif
+
+#ifdef REGISTER_TYPED_TEST_CASE_P
+// CHECK-MESSAGES: [[@LINE-1]]:2: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+#undef REGISTER_TYPED_TEST_CASE_P
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+#define REGISTER_TYPED_TEST_CASE_P REGISTER_TYPED_TEST_SUITE_P
+#endif
+
+#ifdef INSTANTIATE_TYPED_TEST_CASE_P
+// CHECK-MESSAGES: [[@LINE-1]]:2: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+#undef INSTANTIATE_TYPED_TEST_CASE_P
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+#define INSTANTIATE_TYPED_TEST_CASE_P INSTANTIATE_TYPED_TEST_SUITE_P
+#endif
+
+TYPED_TEST_CASE(FooTest, FooTypes);
+TYPED_TEST_CASE_P(FooTest);
+REGISTER_TYPED_TEST_CASE_P(FooTest, FooTestName);
+INSTANTIATE_TYPED_TEST_CASE_P(FooPrefix, FooTest, FooTypes);
+
+// ----------------------------------------------------------------------------
+// testing::Test
+
+class FooTest : public testing::Test {
+public:
+  static void SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: static void SetUpTestSuite();
+  static void TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: static void TearDownTestSuite();
+};
+
+void FooTest::SetUpTestCase() {}
+// CHECK-MESSAGES: [[@LINE-1]]:15: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: void FooTest::SetUpTestSuite() {}
+
+void FooTest::TearDownTestCase() {}
+// CHECK-MESSAGES: [[@LINE-1]]:15: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: void FooTest::TearDownTestSuite() {}
+
+template <typename T> class FooTypedTest : public testing::Test {
+public:
+  static void SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: static void SetUpTestSuite();
+  static void TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: static void TearDownTestSuite();
+};
+
+template <typename T> void FooTypedTest<T>::SetUpTestCase() {}
+// CHECK-MESSAGES: [[@LINE-1]]:45: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: void FooTypedTest<T>::SetUpTestSuite() {}
+
+template <typename T> void FooTypedTest<T>::TearDownTestCase() {}
+// CHECK-MESSAGES: [[@LINE-1]]:45: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: void FooTypedTest<T>::TearDownTestSuite() {}
+
+class BarTest : public testing::Test {
+public:
+  using Test::SetUpTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using Test::SetUpTestSuite;
+  using Test::TearDownTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using Test::TearDownTestSuite;
+};
+
+class BarTest2 : public FooTest {
+public:
+  using FooTest::SetUpTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using FooTest::SetUpTestSuite;
+  using FooTest::TearDownTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using FooTest::TearDownTestSuite;
+};
+
+// If a derived type already has the replacements, we only provide a warning
+// since renaming or deleting the old declarations may not be safe.
+class BarTest3 : public testing::Test {
+ public:
+  static void SetUpTestCase() {}
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  static void SetUpTestSuite() {}
+
+  static void TearDownTestCase() {}
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  static void TearDownTestSuite() {}
+};
+
+namespace nesting_ns {
+namespace testing {
+
+class Test {
+public:
+  static void SetUpTestCase();
+  static void TearDownTestCase();
+};
+
+} // namespace testing
+
+void Test() {
+  testing::Test::SetUpTestCase();
+  testing::Test::TearDownTestCase();
+}
+
+} // namespace nesting_ns
+
+template <typename T>
+void testInstantiationOnlyWarns() {
+  T::SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:6: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  T::TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:6: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+}
+
+#define SET_UP_TEST_CASE_MACRO_REPLACE SetUpTestCase
+#define TEST_SET_UP_TEST_CASE_MACRO_WARN_ONLY ::testing::Test::SetUpTestCase
+
+void setUpTearDownCallAndReference() {
+  testing::Test::SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: testing::Test::SetUpTestSuite();
+  FooTest::SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: FooTest::SetUpTestSuite();
+
+  testing::Test::TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: testing::Test::TearDownTestSuite();
+  FooTest::TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: FooTest::TearDownTestSuite();
+
+  auto F = &testing::Test::SetUpTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto F = &testing::Test::SetUpTestSuite;
+  F = &testing::Test::TearDownTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: F = &testing::Test::TearDownTestSuite;
+  F = &FooTest::SetUpTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:17: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: F = &FooTest::SetUpTestSuite;
+  F = &FooTest::TearDownTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:17: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: F = &FooTest::TearDownTestSuite;
+
+  using MyTest = testing::Test;
+  MyTest::SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: MyTest::SetUpTestSuite();
+  MyTest::TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: MyTest::TearDownTestSuite();
+
+  BarTest3::SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: BarTest3::SetUpTestSuite();
+  BarTest3::TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: BarTest3::TearDownTestSuite();
+
+  testInstantiationOnlyWarns<testing::Test>();
+
+  testing::Test::SET_UP_TEST_CASE_MACRO_REPLACE();
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: testing::Test::SetUpTestSuite();
+  TEST_SET_UP_TEST_CASE_MACRO_WARN_ONLY();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+}
+
+// ----------------------------------------------------------------------------
+// testing::TestInfo
+
+class FooTestInfo : public testing::TestInfo {
+public:
+  const char *test_case_name() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: const char *test_suite_name() const;
+};
+
+const char *FooTestInfo::test_case_name() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:26: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: const char *FooTestInfo::test_suite_name() const {}
+
+class BarTestInfo : public testing::TestInfo {
+public:
+  using TestInfo::test_case_name;
+  // CHECK-MESSAGES: [[@LINE-1]]:19: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using TestInfo::test_suite_name;
+};
+
+class BarTestInfo2 : public FooTestInfo {
+public:
+  using FooTestInfo::test_case_name;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using FooTestInfo::test_suite_name;
+};
+
+class BarTestInfo3 : public testing::TestInfo {
+ public:
+  const char* test_case_name() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  const char* test_suite_name() const;
+};
+
+namespace nesting_ns {
+namespace testing {
+
+class TestInfo {
+public:
+  const char *test_case_name() const;
+};
+
+} // namespace testing
+
+void FuncInfo() {
+  testing::TestInfo t;
+  (void)t.test_case_name();
+}
+
+} // namespace nesting_ns
+
+template <typename T>
+void testInfoInstantiationOnlyWarns() {
+  T t;
+  (void)t.test_case_name();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+}
+
+#define TEST_CASE_NAME_MACRO_REPLACE test_case_name
+#define TEST_CASE_NAME_MACRO_WARN_ONLY testing::TestInfo().test_case_name
+
+void testInfoCallAndReference() {
+  (void)testing::TestInfo().test_case_name();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::TestInfo().test_suite_name();
+  (void)FooTestInfo().test_case_name();
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)FooTestInfo().test_suite_name();
+  auto F1 = &testing::TestInfo::test_case_name;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto F1 = &testing::TestInfo::test_suite_name;
+  auto F2 = &FooTestInfo::test_case_name;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto F2 = &FooTestInfo::test_suite_name;
+  using MyTestInfo = testing::TestInfo;
+  (void)MyTestInfo().test_case_name();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)MyTestInfo().test_suite_name();
+  (void)BarTestInfo3().test_case_name();
+  // CHECK-MESSAGES: [[@LINE-1]]:24: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)BarTestInfo3().test_suite_name();
+
+  testInfoInstantiationOnlyWarns<testing::TestInfo>();
+
+  (void)testing::TestInfo().TEST_CASE_NAME_MACRO_REPLACE();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::TestInfo().test_suite_name();
+  (void)TEST_CASE_NAME_MACRO_WARN_ONLY();
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+}
+
+// ----------------------------------------------------------------------------
+// testing::TestEventListener
+
+class FooTestEventListener : public testing::TestEventListener {
+public:
+  void OnTestCaseStart(const testing::TestCase &) override;
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-MESSAGES: [[@LINE-2]]:39: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: void OnTestSuiteStart(const testing::TestSuite &) override;
+  void OnTestCaseEnd(const testing::TestCase &) override;
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-MESSAGES: [[@LINE-2]]:37: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: void OnTestSuiteEnd(const testing::TestSuite &) override;
+};
+
+void FooTestEventListener::OnTestCaseStart(const testing::TestCase &) {}
+// CHECK-MESSAGES: [[@LINE-1]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-MESSAGES: [[@LINE-2]]:59: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: void FooTestEventListener::OnTestSuiteStart(const testing::TestSuite &) {}
+
+void FooTestEventListener::OnTestCaseEnd(const testing::TestCase &) {}
+// CHECK-MESSAGES: [[@LINE-1]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-MESSAGES: [[@LINE-2]]:57: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: void FooTestEventListener::OnTestSuiteEnd(const testing::TestSuite &) {}
+
+class BarTestEventListener : public testing::TestEventListener {
+public:
+  using TestEventListener::OnTestCaseStart;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using TestEventListener::OnTestSuiteStart;
+  using TestEventListener::OnTestCaseEnd;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using TestEventListener::OnTestSuiteEnd;
+};
+
+class BarTestEventListener2 : public BarTestEventListener {
+public:
+  using BarTestEventListener::OnTestCaseStart;
+  // CHECK-MESSAGES: [[@LINE-1]]:31: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using BarTestEventListener::OnTestSuiteStart;
+  using BarTestEventListener::OnTestCaseEnd;
+  // CHECK-MESSAGES: [[@LINE-1]]:31: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using BarTestEventListener::OnTestSuiteEnd;
+};
+
+class BarTestEventListener3 : public testing::TestEventListener {
+public:
+  void OnTestCaseStart(const testing::TestSuite &) override;
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  void OnTestSuiteStart(const testing::TestSuite &) override;
+
+  void OnTestCaseEnd(const testing::TestSuite &) override;
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  void OnTestSuiteEnd(const testing::TestSuite &) override;
+};
+
+namespace nesting_ns {
+namespace testing {
+
+class TestEventListener {
+public:
+  virtual void OnTestCaseStart(const ::testing::TestCase &);
+  // CHECK-MESSAGES: [[@LINE-1]]:49: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: virtual void OnTestCaseStart(const ::testing::TestSuite &);
+  virtual void OnTestCaseEnd(const ::testing::TestCase &);
+  // CHECK-MESSAGES: [[@LINE-1]]:47: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: virtual void OnTestCaseEnd(const ::testing::TestSuite &);
+};
+
+} // namespace testing
+
+void FuncTestEventListener(::testing::TestCase &Case) {
+  // CHECK-MESSAGES: [[@LINE-1]]:39: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: void FuncTestEventListener(::testing::TestSuite &Case) {
+  testing::TestEventListener().OnTestCaseStart(Case);
+  testing::TestEventListener().OnTestCaseEnd(Case);
+}
+
+} // namespace nesting_ns
+
+template <typename T>
+void testEventListenerInstantiationOnlyWarns() {
+  T().OnTestCaseStart(testing::TestSuite());
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  T().OnTestCaseEnd(testing::TestSuite());
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+}
+
+#define ON_TEST_CASE_START_MACRO_REPLACE OnTestCaseStart
+#define ON_TEST_CASE_START_MACRO_WARN_ONLY                                     \
+  testing::TestEventListener().OnTestCaseStart
+
+#define ON_TEST_CASE_END_MACRO_REPLACE OnTestCaseEnd
+#define ON_TEST_CASE_END_MACRO_WARN_ONLY                                       \
+  testing::TestEventListener().OnTestCaseEnd
+
+void testEventListenerCallAndReference(testing::TestCase &Case) {
+  // CHECK-MESSAGES: [[@LINE-1]]:49: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: void testEventListenerCallAndReference(testing::TestSuite &Case) {
+  testing::TestEventListener().OnTestCaseStart(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:32: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: testing::TestEventListener().OnTestSuiteStart(Case);
+  testing::TestEventListener().OnTestCaseEnd(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:32: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: testing::TestEventListener().OnTestSuiteEnd(Case);
+
+  FooTestEventListener().OnTestCaseStart(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:26: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: FooTestEventListener().OnTestSuiteStart(Case);
+  FooTestEventListener().OnTestCaseEnd(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:26: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: FooTestEventListener().OnTestSuiteEnd(Case);
+
+  auto F1 = &testing::TestEventListener::OnTestCaseStart;
+  // CHECK-MESSAGES: [[@LINE-1]]:42: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto F1 = &testing::TestEventListener::OnTestSuiteStart;
+  F1 = &testing::TestEventListener::OnTestCaseEnd;
+  // CHECK-MESSAGES: [[@LINE-1]]:37: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: F1 = &testing::TestEventListener::OnTestSuiteEnd;
+
+  auto F2 = &FooTestEventListener::OnTestCaseStart;
+  // CHECK-MESSAGES: [[@LINE-1]]:36: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto F2 = &FooTestEventListener::OnTestSuiteStart;
+  F2 = &FooTestEventListener::OnTestCaseEnd;
+  // CHECK-MESSAGES: [[@LINE-1]]:31: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: F2 = &FooTestEventListener::OnTestSuiteEnd;
+
+  BarTestEventListener3().OnTestCaseStart(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: BarTestEventListener3().OnTestSuiteStart(Case);
+  BarTestEventListener3().OnTestCaseEnd(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: BarTestEventListener3().OnTestSuiteEnd(Case);
+
+  testEventListenerInstantiationOnlyWarns<testing::TestEventListener>();
+
+  testing::TestEventListener().ON_TEST_CASE_START_MACRO_REPLACE(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:32: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: testing::TestEventListener().OnTestSuiteStart(Case);
+  ON_TEST_CASE_START_MACRO_WARN_ONLY(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+
+  testing::TestEventListener().ON_TEST_CASE_END_MACRO_REPLACE(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:32: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: testing::TestEventListener().OnTestSuiteEnd(Case);
+  ON_TEST_CASE_END_MACRO_WARN_ONLY(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+}
+
+// ----------------------------------------------------------------------------
+// testing::UnitTest
+
+class FooUnitTest : public testing::UnitTest {
+public:
+  testing::TestCase *current_test_case() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-MESSAGES: [[@LINE-2]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: testing::TestSuite *current_test_suite() const;
+  int successful_test_case_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: int successful_test_suite_count() const;
+  int failed_test_case_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: int failed_test_suite_count() const;
+  int total_test_case_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: int total_test_suite_count() const;
+  int test_case_to_run_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: int test_suite_to_run_count() const;
+  const testing::TestCase *GetTestCase(int) const;
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-MESSAGES: [[@LINE-2]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: const testing::TestSuite *GetTestSuite(int) const;
+};
+
+testing::TestCase *FooUnitTest::current_test_case() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:10: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-MESSAGES: [[@LINE-2]]:33: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: testing::TestSuite *FooUnitTest::current_test_suite() const {}
+int FooUnitTest::successful_test_case_count() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: int FooUnitTest::successful_test_suite_count() const {}
+int FooUnitTest::failed_test_case_count() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: int FooUnitTest::failed_test_suite_count() const {}
+int FooUnitTest::total_test_case_count() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: int FooUnitTest::total_test_suite_count() const {}
+int FooUnitTest::test_case_to_run_count() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: int FooUnitTest::test_suite_to_run_count() const {}
+const testing::TestCase *FooUnitTest::GetTestCase(int) const {}
+// CHECK-MESSAGES: [[@LINE-1]]:16: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-MESSAGES: [[@LINE-2]]:39: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: const testing::TestSuite *FooUnitTest::GetTestSuite(int) const {}
+
+// Type derived from testing::TestCase
+class BarUnitTest : public testing::UnitTest {
+public:
+  using testing::UnitTest::current_test_case;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using testing::UnitTest::current_test_suite;
+  using testing::UnitTest::successful_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using testing::UnitTest::successful_test_suite_count;
+  using testing::UnitTest::failed_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using testing::UnitTest::failed_test_suite_count;
+  using testing::UnitTest::total_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using testing::UnitTest::total_test_suite_count;
+  using testing::UnitTest::test_case_to_run_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using testing::UnitTest::test_suite_to_run_count;
+  using testing::UnitTest::GetTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using testing::UnitTest::GetTestSuite;
+};
+
+class BarUnitTest2 : public BarUnitTest {
+  using BarUnitTest::current_test_case;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using BarUnitTest::current_test_suite;
+  using BarUnitTest::successful_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using BarUnitTest::successful_test_suite_count;
+  using BarUnitTest::failed_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using BarUnitTest::failed_test_suite_count;
+  using BarUnitTest::total_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using BarUnitTest::total_test_suite_count;
+  using BarUnitTest::test_case_to_run_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using BarUnitTest::test_suite_to_run_count;
+  using BarUnitTest::GetTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: using BarUnitTest::GetTestSuite;
+};
+
+class BarUnitTest3 : public testing::UnitTest {
+  testing::TestSuite *current_test_case() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  int successful_test_case_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  int failed_test_case_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  int total_test_case_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  int test_case_to_run_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  const testing::TestSuite *GetTestCase(int) const;
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+
+  testing::TestSuite *current_test_suite() const;
+  int successful_test_suite_count() const;
+  int failed_test_suite_count() const;
+  int total_test_suite_count() const;
+  int test_suite_to_run_count() const;
+  const testing::TestSuite *GetTestSuite(int) const;
+};
+
+namespace nesting_ns {
+namespace testing {
+
+class UnitTest {
+public:
+  ::testing::TestSuite *current_test_case() const;
+  int successful_test_case_count() const;
+  int failed_test_case_count() const;
+  int total_test_case_count() const;
+  int test_case_to_run_count() const;
+  const ::testing::TestSuite *GetTestCase(int) const;
+};
+
+} // namespace testing
+
+void FuncUnitTest() {
+  testing::UnitTest t;
+  (void)t.current_test_case();
+  (void)t.successful_test_case_count();
+  (void)t.failed_test_case_count();
+  (void)t.total_test_case_count();
+  (void)t.test_case_to_run_count();
+  (void)t.GetTestCase(0);
+}
+
+} // namespace nesting_ns
+
+template <typename T>
+void unitTestInstantiationOnlyWarns() {
+  T t;
+  (void)t.current_test_case();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  (void)t.successful_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  (void)t.failed_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  (void)t.total_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  (void)t.test_case_to_run_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  (void)t.GetTestCase(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+}
+
+#define UNIT_TEST_NAME_MACRO_REPLACE1 current_test_case
+#define UNIT_TEST_NAME_MACRO_REPLACE2 successful_test_case_count
+#define UNIT_TEST_NAME_MACRO_REPLACE3 failed_test_case_count
+#define UNIT_TEST_NAME_MACRO_REPLACE4 total_test_case_count
+#define UNIT_TEST_NAME_MACRO_REPLACE5 test_case_to_run_count
+#define UNIT_TEST_NAME_MACRO_REPLACE6 GetTestCase
+#define UNIT_TEST_NAME_MACRO_WARN_ONLY1 testing::UnitTest().current_test_case
+#define UNIT_TEST_NAME_MACRO_WARN_ONLY2                                        \
+  testing::UnitTest().successful_test_case_count
+#define UNIT_TEST_NAME_MACRO_WARN_ONLY3                                        \
+  testing::UnitTest().failed_test_case_count
+#define UNIT_TEST_NAME_MACRO_WARN_ONLY4                                        \
+  testing::UnitTest().total_test_case_count
+#define UNIT_TEST_NAME_MACRO_WARN_ONLY5                                        \
+  testing::UnitTest().test_case_to_run_count
+#define UNIT_TEST_NAME_MACRO_WARN_ONLY6 testing::UnitTest().GetTestCase
+
+void unitTestCallAndReference() {
+  (void)testing::UnitTest().current_test_case();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::UnitTest().current_test_suite();
+  (void)testing::UnitTest().successful_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::UnitTest().successful_test_suite_count();
+  (void)testing::UnitTest().failed_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::UnitTest().failed_test_suite_count();
+  (void)testing::UnitTest().total_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::UnitTest().total_test_suite_count();
+  (void)testing::UnitTest().test_case_to_run_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::UnitTest().test_suite_to_run_count();
+  (void)testing::UnitTest().GetTestCase(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::UnitTest().GetTestSuite(0);
+
+  (void)FooUnitTest().current_test_case();
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)FooUnitTest().current_test_suite();
+  (void)FooUnitTest().successful_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)FooUnitTest().successful_test_suite_count();
+  (void)FooUnitTest().failed_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)FooUnitTest().failed_test_suite_count();
+  (void)FooUnitTest().total_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)FooUnitTest().total_test_suite_count();
+  (void)FooUnitTest().test_case_to_run_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)FooUnitTest().test_suite_to_run_count();
+  (void)FooUnitTest().GetTestCase(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)FooUnitTest().GetTestSuite(0);
+
+  auto U1 = &testing::UnitTest::current_test_case;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto U1 = &testing::UnitTest::current_test_suite;
+  auto U2 = &testing::UnitTest::successful_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto U2 = &testing::UnitTest::successful_test_suite_count;
+  auto U3 = &testing::UnitTest::failed_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto U3 = &testing::UnitTest::failed_test_suite_count;
+  auto U4 = &testing::UnitTest::total_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto U4 = &testing::UnitTest::total_test_suite_count;
+  auto U5 = &testing::UnitTest::test_case_to_run_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto U5 = &testing::UnitTest::test_suite_to_run_count;
+  auto U6 = &testing::UnitTest::GetTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto U6 = &testing::UnitTest::GetTestSuite;
+
+  auto F1 = &FooUnitTest::current_test_case;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto F1 = &FooUnitTest::current_test_suite;
+  auto F2 = &FooUnitTest::successful_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto F2 = &FooUnitTest::successful_test_suite_count;
+  auto F3 = &FooUnitTest::failed_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto F3 = &FooUnitTest::failed_test_suite_count;
+  auto F4 = &FooUnitTest::total_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto F4 = &FooUnitTest::total_test_suite_count;
+  auto F5 = &FooUnitTest::test_case_to_run_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto F5 = &FooUnitTest::test_suite_to_run_count;
+  auto F6 = &FooUnitTest::GetTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: auto F6 = &FooUnitTest::GetTestSuite;
+
+  using MyUnitTest = testing::UnitTest;
+  (void)MyUnitTest().current_test_case();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)MyUnitTest().current_test_suite();
+  (void)MyUnitTest().successful_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)MyUnitTest().successful_test_suite_count();
+  (void)MyUnitTest().failed_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)MyUnitTest().failed_test_suite_count();
+  (void)MyUnitTest().total_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)MyUnitTest().total_test_suite_count();
+  (void)MyUnitTest().test_case_to_run_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)MyUnitTest().test_suite_to_run_count();
+  (void)MyUnitTest().GetTestCase(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)MyUnitTest().GetTestSuite(0);
+
+  unitTestInstantiationOnlyWarns<testing::UnitTest>();
+
+  (void)testing::UnitTest().UNIT_TEST_NAME_MACRO_REPLACE1();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::UnitTest().current_test_suite();
+  (void)testing::UnitTest().UNIT_TEST_NAME_MACRO_REPLACE2();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::UnitTest().successful_test_suite_count();
+  (void)testing::UnitTest().UNIT_TEST_NAME_MACRO_REPLACE3();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::UnitTest().failed_test_suite_count();
+  (void)testing::UnitTest().UNIT_TEST_NAME_MACRO_REPLACE4();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::UnitTest().total_test_suite_count();
+  (void)testing::UnitTest().UNIT_TEST_NAME_MACRO_REPLACE5();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::UnitTest().test_suite_to_run_count();
+  (void)testing::UnitTest().UNIT_TEST_NAME_MACRO_REPLACE6(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)testing::UnitTest().GetTestSuite(0);
+
+  UNIT_TEST_NAME_MACRO_WARN_ONLY1();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  UNIT_TEST_NAME_MACRO_WARN_ONLY2();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  UNIT_TEST_NAME_MACRO_WARN_ONLY3();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  UNIT_TEST_NAME_MACRO_WARN_ONLY4();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  UNIT_TEST_NAME_MACRO_WARN_ONLY5();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  UNIT_TEST_NAME_MACRO_WARN_ONLY6(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+}
+
+// ----------------------------------------------------------------------------
+// testing::TestCase
+
+template <typename T>
+void TestCaseInTemplate() {
+  T t;
+
+  testing::TestCase Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: testing::TestSuite Case;
+}
+
+#define TEST_CASE_CAN_FIX TestCase
+#define TEST_CASE_WARN_ONLY testing::TestCase
+
+const testing::TestCase *testCaseUses(const testing::TestCase &Case) {
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-MESSAGES: [[@LINE-2]]:54: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: const testing::TestSuite *testCaseUses(const testing::TestSuite &Case) {
+
+  // No change for implicit declarations:
+  auto Lambda = [&Case]() {};
+
+  TestCaseInTemplate<testing::TestCase>();
+  // CHECK-MESSAGES: [[@LINE-1]]:31: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: TestCaseInTemplate<testing::TestSuite>();
+
+  testing::TEST_CASE_CAN_FIX C1;
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: testing::TestSuite C1;
+  TEST_CASE_WARN_ONLY C2;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+
+  (void)new testing::TestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)new testing::TestSuite();
+  const testing::TestCase *Result = &Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: const testing::TestSuite *Result = &Case;
+  return Result;
+}
+
+struct TestCaseHolder {
+  testing::TestCase Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: testing::TestSuite Case;
+};
+
+class MyTest : public testing::TestCase {};
+// CHECK-MESSAGES: [[@LINE-1]]:32: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: class MyTest : public testing::TestSuite {};
+
+template <typename T = testing::TestCase>
+// CHECK-MESSAGES: [[@LINE-1]]:33: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: template <typename T = testing::TestSuite>
+class TestTypeHolder {};
+
+template <>
+class TestTypeHolder<testing::TestCase> {};
+// CHECK-MESSAGES: [[@LINE-1]]:31: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: class TestTypeHolder<testing::TestSuite> {};
+
+namespace shadow_using_ns {
+
+using testing::TestCase;
+// CHECK-MESSAGES: [[@LINE-1]]:16: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: using testing::TestSuite;
+
+const TestCase *testCaseUses(const TestCase &Case) {
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-MESSAGES: [[@LINE-2]]:36: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: const TestSuite *testCaseUses(const TestSuite &Case) {
+
+  // No change for implicit declarations:
+  auto Lambda = [&Case]() {};
+
+  (void)new TestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)new TestSuite();
+  const TestCase *Result = &Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: const TestSuite *Result = &Case;
+  return Result;
+}
+
+struct TestCaseHolder {
+  TestCase Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: TestSuite Case;
+};
+
+class MyTest : public TestCase {};
+// CHECK-MESSAGES: [[@LINE-1]]:23: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: class MyTest : public TestSuite {};
+
+template <typename T = TestCase>
+// CHECK-MESSAGES: [[@LINE-1]]:24: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: template <typename T = TestSuite>
+class TestTypeHolder {};
+
+template <>
+class TestTypeHolder<TestCase> {};
+// CHECK-MESSAGES: [[@LINE-1]]:22: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: class TestTypeHolder<TestSuite> {};
+
+} // namespace shadow_using_ns
+
+const shadow_using_ns::TestCase *shadowTestCaseUses(
+    const shadow_using_ns::TestCase &Case) {
+  // CHECK-MESSAGES: [[@LINE-2]]:24: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-MESSAGES: [[@LINE-2]]:28: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: const shadow_using_ns::TestSuite *shadowTestCaseUses(
+  // CHECK-FIXES: const shadow_using_ns::TestSuite &Case) {
+
+  // No match for implicit declarations, as in the lambda capture:
+  auto Lambda = [&Case]() {};
+
+  (void)new shadow_using_ns::TestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:30: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: (void)new shadow_using_ns::TestSuite();
+  const shadow_using_ns::TestCase *Result = &Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:26: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: const shadow_using_ns::TestSuite *Result = &Case;
+  return Result;
+}
+
+struct ShadowTestCaseHolder {
+  shadow_using_ns::TestCase Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+  // CHECK-FIXES: shadow_using_ns::TestSuite Case;
+};
+
+class ShadowMyTest : public shadow_using_ns::TestCase {};
+// CHECK-MESSAGES: [[@LINE-1]]:46: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: class ShadowMyTest : public shadow_using_ns::TestSuite {};
+
+template <typename T = shadow_using_ns::TestCase>
+// CHECK-MESSAGES: [[@LINE-1]]:41: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: template <typename T = shadow_using_ns::TestSuite>
+class ShadowTestTypeHolder {};
+
+template <>
+class ShadowTestTypeHolder<shadow_using_ns::TestCase> {};
+// CHECK-MESSAGES: [[@LINE-1]]:45: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: class ShadowTestTypeHolder<shadow_using_ns::TestSuite> {};
+
+namespace typedef_ns {
+
+typedef testing::TestCase MyTestCase;
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: typedef testing::TestSuite MyTestCase;
+
+const MyTestCase *testCaseUses(const MyTestCase &Case) {
+  auto Lambda = [&Case]() {};
+  (void)new MyTestCase();
+  const MyTestCase *Result = &Case;
+  return Result;
+}
+
+struct TestCaseHolder {
+  MyTestCase Case;
+};
+
+class MyTest : public MyTestCase {};
+
+template <typename T = MyTestCase>
+class TestTypeHolder {};
+
+template <>
+class TestTypeHolder<MyTestCase> {};
+
+} // namespace typedef_ns
+
+const typedef_ns::MyTestCase *typedefTestCaseUses(
+    const typedef_ns::MyTestCase &Case) {
+  auto Lambda = [&Case]() {};
+  (void)new typedef_ns::MyTestCase();
+  const typedef_ns::MyTestCase *Result = &Case;
+  return Result;
+}
+
+struct TypedefTestCaseHolder {
+  typedef_ns::MyTestCase Case;
+};
+
+class TypedefMyTest : public typedef_ns::MyTestCase {};
+template <typename T = typedef_ns::MyTestCase> class TypedefTestTypeHolder {};
+template <> class TypedefTestTypeHolder<typedef_ns::MyTestCase> {};
+
+namespace alias_ns {
+
+using MyTestCase = testing::TestCase;
+// CHECK-MESSAGES: [[@LINE-1]]:29: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: using MyTestCase = testing::TestSuite;
+
+const MyTestCase *testCaseUses(const MyTestCase &Case) {
+  auto Lambda = [&Case]() {};
+  (void)new MyTestCase();
+  const MyTestCase *Result = &Case;
+  return Result;
+}
+
+struct TestCaseHolder {
+  MyTestCase Case;
+};
+
+class MyTest : public MyTestCase {};
+template <typename T = MyTestCase> class TestTypeHolder {};
+template <> class TestTypeHolder<MyTestCase> {};
+
+} // namespace alias_ns
+
+const alias_ns::MyTestCase *aliasTestCaseUses(
+    const alias_ns::MyTestCase &Case) {
+  auto Lambda = [&Case]() {};
+  (void)new alias_ns::MyTestCase();
+  const alias_ns::MyTestCase *Result = &Case;
+  return Result;
+}
+
+struct AliasTestCaseHolder {
+  alias_ns::MyTestCase Case;
+};
+
+class AliasMyTest : public alias_ns::MyTestCase {};
+template <typename T = alias_ns::MyTestCase> class AliasTestTypeHolder {};
+template <> class AliasTestTypeHolder<alias_ns::MyTestCase> {};
+
+template <typename T>
+void templateFunction(const T& t) {
+  (void)t.current_test_case();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Googletest APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+}
+
+void instantiateTemplateFunction(const testing::UnitTest &Test) {
+  templateFunction(Test);
+}
Index: clang-tools-extra/test/clang-tidy/Inputs/gtest/gtest.h
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/Inputs/gtest/gtest.h
@@ -0,0 +1,66 @@
+#ifndef THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_H_
+#define THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_H_
+
+#include "gtest/gtest-typed-test.h"
+
+namespace testing {
+
+class Test {
+public:
+  static void SetUpTestCase();
+  static void TearDownTestCase();
+
+  static void SetUpTestSuite();
+  static void TearDownTestSuite();
+};
+
+class TestSuite {};
+using TestCase = TestSuite;
+
+class TestInfo {
+public:
+  const char *test_case_name() const;
+
+  const char *test_suite_name() const;
+};
+
+class TestEventListener {
+public:
+  virtual void OnTestCaseStart(const TestCase &);
+  virtual void OnTestCaseEnd(const TestCase &);
+
+  virtual void OnTestSuiteStart(const TestCase &);
+  virtual void OnTestSuiteEnd(const TestCase &);
+};
+
+class EmptyTestEventListener : public TestEventListener {
+public:
+  void OnTestCaseStart(const TestCase &) override;
+  void OnTestCaseEnd(const TestCase &) override;
+
+  void OnTestSuiteStart(const TestCase &) override;
+  void OnTestSuiteEnd(const TestCase &) override;
+};
+
+class UnitTest {
+public:
+  static UnitTest *GetInstance();
+
+  TestCase *current_test_case() const;
+  int successful_test_case_count() const;
+  int failed_test_case_count() const;
+  int total_test_case_count() const;
+  int test_case_to_run_count() const;
+  const TestCase *GetTestCase(int) const;
+
+  TestSuite *current_test_suite() const;
+  int successful_test_suite_count() const;
+  int failed_test_suite_count() const;
+  int total_test_suite_count() const;
+  int test_suite_to_run_count() const;
+  const TestSuite *GetTestSuite(int) const;
+};
+
+} // namespace testing
+
+#endif // THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_H_
Index: clang-tools-extra/test/clang-tidy/Inputs/gtest/gtest-typed-test.h
===================================================================
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/Inputs/gtest/gtest-typed-test.h
@@ -0,0 +1,16 @@
+#ifndef THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_TYPED_TEST_H_
+#define THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_TYPED_TEST_H_
+
+#define TYPED_TEST_SUITE(CaseName, Types, ...)
+#define TYPED_TEST_CASE TYPED_TEST_SUITE
+
+#define TYPED_TEST_SUITE_P(SuiteName)
+#define TYPED_TEST_CASE_P TYPED_TEST_SUITE_P
+
+#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...)
+#define REGISTER_TYPED_TEST_CASE_P REGISTER_TYPED_TEST_SUITE_P
+
+#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...)
+#define INSTANTIATE_TYPED_TEST_CASE_P INSTANTIATE_TYPED_TEST_SUITE_P
+
+#endif  // THIRD_PARTY_LLVM_LLVM_TOOLS_CLANG_TOOLS_EXTRA_TEST_CLANG_TIDY_INPUTS_GTEST_GTEST_TYPED_TEST_H_
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -149,6 +149,7 @@
    google-runtime-int
    google-runtime-operator
    google-runtime-references
+   google-upgrade-googletest-case
    hicpp-avoid-c-arrays (redirects to modernize-avoid-c-arrays) <hicpp-avoid-c-arrays>
    hicpp-avoid-goto
    hicpp-braces-around-statements (redirects to readability-braces-around-statements) <hicpp-braces-around-statements>
Index: clang-tools-extra/docs/clang-tidy/checks/google-upgrade-googletest-case.rst
===================================================================
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/google-upgrade-googletest-case.rst
@@ -0,0 +1,49 @@
+.. title:: clang-tidy - google-upgrade-googletest-case
+
+google-upgrade-googletest-case
+==============================
+
+Finds uses of deprecated Googletest APIs with names containing ``case`` and
+replaces them with equivalent APIs with ``suite``.
+
+All names containing ``case`` are being replaced to be consistent with the
+meanings of "test case" and "test suite" as used by the International
+Software Testing Qualifications Board and ISO 29119.
+
+The affected APIs are :
+
+- Member functions of ``testing::Test``, ``testing::TestInfo``,
+  ``testing::TestEventListener``, ``testing::UnitTest``, and any type inheriting
+  from these types
+- The macros ``TYPED_TEST_CASE``, ``TYPED_TEST_CASE_P``,
+  ``REGISTER_TYPED_TEST_CASE_P``, and ``INSTANTIATE_TYPED_TEST_CASE_P``
+- The type alias ``testing::TestCase``
+
+Examples of fixes created by this check:
+
+.. code-block:: c++
+
+  class FooTest : public testing::Test {
+  public:
+    static void SetUpTestCase();
+    static void TearDownTestCase();
+  };
+
+  TYPED_TEST_CASE(BarTest, BarTypes);
+
+becomes
+
+.. code-block:: c++
+
+  class FooTest : public testing::Test {
+  public:
+    static void SetUpTestSuite();
+    static void TearDownTestSuite();
+  };
+
+  TYPED_TEST_SUITE(BarTest, BarTypes);
+
+For better consistency of user code, the check renames both virtual and
+non-virtual member functions with matching names in derived types. The check
+tries to provide a only warning when a fix cannot be made safely, as is the case
+with some template and macro uses.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===================================================================
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -128,6 +128,12 @@
   Checks for calls to ``+new`` or overrides of it, which are prohibited by the
   Google Objective-C style guide.
 
+- New :doc:`google-upgrade-googletest-case
+  <clang-tidy/checks/google-upgrade-googletest-case>` check.
+
+  Finds uses of deprecated Googletest APIs with names containing ``case`` and
+  replaces them with equivalent APIs with ``suite``.
+
 - New :doc:`objc-super-self <clang-tidy/checks/objc-super-self>` check.
 
   Finds invocations of ``-self`` on super instances in initializers of
Index: clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.h
@@ -0,0 +1,42 @@
+//===--- UpgradeGoogletestCaseCheck.h - clang-tidy --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_UPGRADEGOOGLETESTCASECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_UPGRADEGOOGLETESTCASECHECK_H
+
+#include "../ClangTidyCheck.h"
+
+#include <unordered_set>
+
+namespace clang {
+namespace tidy {
+namespace google {
+
+/// Finds uses of deprecated Googletest APIs with names containing "case" and
+/// replaces them with equivalent names containing "suite".
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/google-upgrade-googletest-case.html
+class UpgradeGoogletestCaseCheck : public ClangTidyCheck {
+public:
+  UpgradeGoogletestCaseCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+                           Preprocessor *ModuleExpanderPP) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  std::unordered_set<unsigned> MatchedTemplateLocations;
+};
+
+} // namespace google
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_UPGRADEGOOGLETESTCASECHECK_H
Index: clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp
@@ -0,0 +1,317 @@
+//===--- UpgradeGoogletestCaseCheck.cpp - clang-tidy ----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "UpgradeGoogletestCaseCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace google {
+namespace {
+
+const llvm::StringRef CheckMessage =
+    "Googletest APIs named with 'case' are deprecated; use equivalent APIs "
+    "named with 'suite'";
+
+llvm::Optional<llvm::StringRef> getNewMacroName(llvm::StringRef MacroName) {
+  std::pair<llvm::StringRef, llvm::StringRef> ReplacementMap[] = {
+      {"TYPED_TEST_CASE", "TYPED_TEST_SUITE"},
+      {"TYPED_TEST_CASE_P", "TYPED_TEST_SUITE_P"},
+      {"REGISTER_TYPED_TEST_CASE_P", "REGISTER_TYPED_TEST_SUITE_P"},
+      {"INSTANTIATE_TYPED_TEST_CASE_P", "INSTANTIATE_TYPED_TEST_SUITE_P"},
+      {"INSTANTIATE_TEST_CASE_P", "INSTANTIATE_TEST_SUITE_P"},
+  };
+
+  for (auto &Mapping : ReplacementMap) {
+    if (MacroName == Mapping.first)
+      return Mapping.second;
+  }
+
+  return llvm::None;
+}
+
+class UpgradeGoogletestCasePPCallback : public PPCallbacks {
+public:
+  UpgradeGoogletestCasePPCallback(UpgradeGoogletestCaseCheck *Check,
+                                  Preprocessor *PP)
+      : Check(Check), PP(PP) {}
+
+  void MacroExpands(const Token &MacroNameTok, const MacroDefinition &MD,
+                    SourceRange Range, const MacroArgs *) override {
+    MacroUsed(MacroNameTok, MD, Range.getBegin(), CheckAction::Rename);
+  }
+
+  void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD,
+                      const MacroDirective *Undef) override {
+    if (Undef != nullptr)
+      MacroUsed(MacroNameTok, MD, Undef->getLocation(), CheckAction::Warn);
+  }
+
+  void Defined(const Token &MacroNameTok, const MacroDefinition &MD,
+               SourceRange Range) override {
+    MacroUsed(MacroNameTok, MD, Range.getBegin(), CheckAction::Warn);
+  }
+
+  void Ifdef(SourceLocation Loc, const Token &MacroNameTok,
+             const MacroDefinition &MD) override {
+    MacroUsed(MacroNameTok, MD, Loc, CheckAction::Warn);
+  }
+
+  void Ifndef(SourceLocation Loc, const Token &MacroNameTok,
+              const MacroDefinition &MD) override {
+    MacroUsed(MacroNameTok, MD, Loc, CheckAction::Warn);
+  }
+
+private:
+  enum class CheckAction { Warn, Rename };
+
+  void MacroUsed(const clang::Token &MacroNameTok, const MacroDefinition &MD,
+                 SourceLocation Loc, CheckAction Action) {
+    std::string Name = PP->getSpelling(MacroNameTok);
+
+    llvm::Optional<llvm::StringRef> Replacement = getNewMacroName(Name);
+    if (!Replacement)
+      return;
+
+    StringRef FileName = PP->getSourceManager().getFilename(
+        MD.getMacroInfo()->getDefinitionLoc());
+    if (!FileName.endswith("gtest/gtest-typed-test.h"))
+      return;
+
+    DiagnosticBuilder Diag = Check->diag(Loc, CheckMessage);
+
+    if (Action == CheckAction::Rename)
+      Diag << FixItHint::CreateReplacement(
+          CharSourceRange::getTokenRange(Loc, Loc), *Replacement);
+  }
+
+  UpgradeGoogletestCaseCheck *Check;
+  Preprocessor *PP;
+};
+
+} // namespace
+
+void UpgradeGoogletestCaseCheck::registerPPCallbacks(const SourceManager &,
+                                                     Preprocessor *PP,
+                                                     Preprocessor *) {
+  PP->addPPCallbacks(
+      llvm::make_unique<UpgradeGoogletestCasePPCallback>(this, PP));
+}
+
+void UpgradeGoogletestCaseCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  auto LocationFilter =
+      unless(isExpansionInFileMatching("gtest/gtest(-typed-test)?\\.h$"));
+
+  // Matchers for the member functions that are being renamed:
+  auto Methods =
+      cxxMethodDecl(
+          anyOf(
+              cxxMethodDecl(
+                  hasAnyName("SetUpTestCase", "TearDownTestCase"),
+                  ofClass(cxxRecordDecl(isSameOrDerivedFrom("::testing::Test"))
+                              .bind("class"))),
+              cxxMethodDecl(hasName("test_case_name"),
+                            ofClass(cxxRecordDecl(isSameOrDerivedFrom(
+                                                      "::testing::TestInfo"))
+                                        .bind("class"))),
+              cxxMethodDecl(
+                  hasAnyName("OnTestCaseStart", "OnTestCaseEnd"),
+                  ofClass(cxxRecordDecl(isSameOrDerivedFrom(
+                                            "::testing::TestEventListener"))
+                              .bind("class"))),
+              cxxMethodDecl(
+                  hasAnyName("current_test_case", "successful_test_case_count",
+                             "failed_test_case_count", "total_test_case_count",
+                             "test_case_to_run_count", "GetTestCase"),
+                  ofClass(
+                      cxxRecordDecl(isSameOrDerivedFrom("::testing::UnitTest"))
+                          .bind("class")))))
+          .bind("method");
+
+  Finder->addMatcher(expr(anyOf(callExpr(callee(Methods)).bind("call"),
+                                declRefExpr(to(Methods)).bind("ref")),
+                          LocationFilter),
+                     this);
+
+  Finder->addMatcher(
+      usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(Methods)), LocationFilter)
+          .bind("using"),
+      this);
+
+  Finder->addMatcher(cxxMethodDecl(Methods, LocationFilter), this);
+
+  // Matchers for `TestCase` -> `TestSuite`:
+  auto TestCaseTypeAlias =
+      typeAliasDecl(hasName("::testing::TestCase")).bind("test-case");
+  Finder->addMatcher(
+      typeLoc(loc(qualType(typedefType(hasDeclaration(TestCaseTypeAlias)))),
+              unless(hasAncestor(decl(isImplicit()))), LocationFilter)
+          .bind("typeloc"),
+      this);
+  Finder->addMatcher(
+      usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(TestCaseTypeAlias)))
+          .bind("using"),
+      this);
+}
+
+namespace {
+
+llvm::StringRef getNewMethodName(llvm::StringRef CurrentName) {
+  std::pair<llvm::StringRef, llvm::StringRef> ReplacementMap[] = {
+      {"SetUpTestCase", "SetUpTestSuite"},
+      {"TearDownTestCase", "TearDownTestSuite"},
+      {"test_case_name", "test_suite_name"},
+      {"OnTestCaseStart", "OnTestSuiteStart"},
+      {"OnTestCaseEnd", "OnTestSuiteEnd"},
+      {"current_test_case", "current_test_suite"},
+      {"successful_test_case_count", "successful_test_suite_count"},
+      {"failed_test_case_count", "failed_test_suite_count"},
+      {"total_test_case_count", "total_test_suite_count"},
+      {"test_case_to_run_count", "test_suite_to_run_count"},
+      {"GetTestCase", "GetTestSuite"}};
+
+  for (auto &Mapping : ReplacementMap) {
+    if (CurrentName == Mapping.first)
+      return Mapping.second;
+  }
+
+  llvm_unreachable("Unexpected function name");
+}
+
+template <typename NodeType>
+bool isInInstantiation(const NodeType &Node,
+                       const MatchFinder::MatchResult &Result) {
+  return !match(isInTemplateInstantiation(), Node, *Result.Context).empty();
+}
+
+template <typename NodeType>
+bool isInTemplate(const NodeType &Node,
+                  const MatchFinder::MatchResult &Result) {
+  internal::Matcher<NodeType> IsInsideTemplate =
+      hasAncestor(decl(anyOf(classTemplateDecl(), functionTemplateDecl())));
+  return !match(IsInsideTemplate, Node, *Result.Context).empty();
+}
+
+bool derivedTypeHasReplacementMethod(const MatchFinder::MatchResult &Result,
+                                     llvm::StringRef ReplacementMethod) {
+  const auto *Class = Result.Nodes.getNodeAs<CXXRecordDecl>("class");
+  return !match(cxxRecordDecl(
+                    unless(isExpansionInFileMatching(
+                        "gtest/gtest(-typed-test)?\\.h$")),
+                    hasMethod(cxxMethodDecl(hasName(ReplacementMethod)))),
+                *Class, *Result.Context)
+              .empty();
+}
+
+CharSourceRange getAliasNameRange(const MatchFinder::MatchResult &Result) {
+  if (const auto *Using = Result.Nodes.getNodeAs<UsingDecl>("using")) {
+    return CharSourceRange::getTokenRange(
+        Using->getNameInfo().getSourceRange());
+  }
+  return CharSourceRange::getTokenRange(
+      Result.Nodes.getNodeAs<TypeLoc>("typeloc")->getSourceRange());
+}
+
+} // namespace
+
+void UpgradeGoogletestCaseCheck::check(const MatchFinder::MatchResult &Result) {
+  llvm::StringRef ReplacementText;
+  CharSourceRange ReplacementRange;
+  if (const auto *Method = Result.Nodes.getNodeAs<CXXMethodDecl>("method")) {
+    ReplacementText = getNewMethodName(Method->getName());
+
+    bool IsInInstantiation;
+    bool IsInTemplate;
+    bool AddFix = true;
+    if (const auto *Call = Result.Nodes.getNodeAs<CXXMemberCallExpr>("call")) {
+      const auto *Callee = llvm::cast<MemberExpr>(Call->getCallee());
+      ReplacementRange = CharSourceRange::getTokenRange(Callee->getMemberLoc(),
+                                                        Callee->getMemberLoc());
+      IsInInstantiation = isInInstantiation(*Call, Result);
+      IsInTemplate = isInTemplate<Stmt>(*Call, Result);
+    } else if (const auto *Ref = Result.Nodes.getNodeAs<DeclRefExpr>("ref")) {
+      ReplacementRange =
+          CharSourceRange::getTokenRange(Ref->getNameInfo().getSourceRange());
+      IsInInstantiation = isInInstantiation(*Ref, Result);
+      IsInTemplate = isInTemplate<Stmt>(*Ref, Result);
+    } else if (const auto *Using = Result.Nodes.getNodeAs<UsingDecl>("using")) {
+      ReplacementRange =
+          CharSourceRange::getTokenRange(Using->getNameInfo().getSourceRange());
+      IsInInstantiation = isInInstantiation(*Using, Result);
+      IsInTemplate = isInTemplate<Decl>(*Using, Result);
+    } else {
+      // This branch means we have matched a function declaration / definition
+      // either for a function from googletest or for a function in a derived
+      // class.
+
+      ReplacementRange = CharSourceRange::getTokenRange(
+          Method->getNameInfo().getSourceRange());
+      IsInInstantiation = isInInstantiation(*Method, Result);
+      IsInTemplate = isInTemplate<Decl>(*Method, Result);
+
+      // If the type of the matched method is strictly derived from a googletest
+      // type and has both the old and new member function names, then we cannot
+      // safely rename (or delete) the old name version.
+      AddFix = !derivedTypeHasReplacementMethod(Result, ReplacementText);
+    }
+
+    if (IsInInstantiation) {
+      if (MatchedTemplateLocations.count(
+              ReplacementRange.getBegin().getRawEncoding()) == 0) {
+        // For each location matched in a template instantiation, we check if
+        // the location can also be found in `MatchedTemplateLocations`. If it
+        // is not found, that means the expression did not create a match
+        // without the instantiation and depends on template parameters. A
+        // manual fix is probably required so we provide only a warning.
+        diag(ReplacementRange.getBegin(), CheckMessage);
+      }
+      return;
+    }
+
+    if (IsInTemplate) {
+      // We gather source locations from template matches not in template
+      // instantiations for future matches.
+      MatchedTemplateLocations.insert(
+          ReplacementRange.getBegin().getRawEncoding());
+    }
+
+    if (!AddFix) {
+      diag(ReplacementRange.getBegin(), CheckMessage);
+      return;
+    }
+  } else {
+    // This is a match for `TestCase` to `TestSuite` refactoring.
+    ReplacementText = "TestSuite";
+    ReplacementRange = getAliasNameRange(Result);
+
+    // We do not need to keep track of template instantiations for this branch,
+    // because we are matching a `TypeLoc` for the alias declaration. Templates
+    // will only be instantiated with the true type name, `TestSuite`.
+  }
+
+  DiagnosticBuilder Diag = diag(ReplacementRange.getBegin(), CheckMessage);
+
+  ReplacementRange = Lexer::makeFileCharRange(
+      ReplacementRange, *Result.SourceManager, Result.Context->getLangOpts());
+  if (ReplacementRange.isInvalid())
+    // An invalid source range likely means we are inside a macro body. A manual
+    // fix is likely needed so we do not create a fix-it hint.
+    return;
+
+  Diag << FixItHint::CreateReplacement(ReplacementRange, ReplacementText);
+}
+
+} // namespace google
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp
===================================================================
--- clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp
+++ clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp
@@ -38,6 +38,8 @@
 class GoogleModule : public ClangTidyModule {
  public:
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+    CheckFactories.registerCheck<UpgradeGoogletestCaseCheck>(
+        "google-upgrade-googletest-case");
     CheckFactories.registerCheck<build::ExplicitMakePairCheck>(
         "google-build-explicit-make-pair");
     CheckFactories.registerCheck<build::UnnamedNamespaceInHeaderCheck>(
Index: clang-tools-extra/clang-tidy/google/CMakeLists.txt
===================================================================
--- clang-tools-extra/clang-tidy/google/CMakeLists.txt
+++ clang-tools-extra/clang-tidy/google/CMakeLists.txt
@@ -17,6 +17,7 @@
   OverloadedUnaryAndCheck.cpp
   TodoCommentCheck.cpp
   UnnamedNamespaceInHeaderCheck.cpp
+  UpgradeGoogletestCaseCheck.cpp
   UsingNamespaceDirectiveCheck.cpp
 
   LINK_LIBS
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to