Эх сурвалжийг харах

Use upstream GoogleTest and add related test utils. (#876)

This moves over to the vanilla upstream GoogleTest pulled in the more
expected manner with Bazel. It also adds Abseil and Google Benchmark
libraries in the same fashion (there are cross dependencies here).

As part of this, also introduce a dependency check test that can enforce
basic layering of dependencies. For example, this lets us ensure that
non-test Carbon code only depends on LLVM and Clang despite having other
libraries available. There remains some cleanup to improve the way these
dependency tests work, but this at least ensures we don't regress.

I've also provided workarounds to allow both Carbon code and LLVM code
to freely be used with GoogleTest (and other `std::ostream` based
output code). This is done by extending the code in
`//common/ostream.h`. One downside is that it requires opening the
`llvm` namespace and adding an ADL_found overload there. I think on
balance this is still a win and doesn't make me too nervous.

The new version of GoogleTest requires printing more often from matchers
and so I've also added several printing routines to types that
previously didn't require them. Otherwise, most of the updates are just
using the more conventional upstream style of including the headers and
adding `ostream.h` where it is needed.

I did consider moving code over to use `std::ostream` instead of LLVM's
`raw_ostream`, but the advantages of not doing virtual dispatch still
seem significant, and it also seems good to retain access to LLVM's
formatting utilities built around `raw_ostream` given that we can't pull
arbitrary dependencies into Carbon code outside of test code.

All of this was slightly motivated by requests for newer features in
GoogleTest, but much more-so by my desire to have access to Google
Benchmark and Abseil when writing benchmarks. For example, using
Abseil's random number generator seems extremely helpful when generating
inputs for benchmarks. The growing dependencies between these packages
further motivated me to just pull them all in and ensure they worked
well.
Chandler Carruth 4 жил өмнө
parent
commit
5f67029479
44 өөрчлөгдсөн 422 нэмэгдсэн , 99 устгасан
  1. 39 0
      WORKSPACE
  2. 87 0
      bazel/check_deps/BUILD
  3. 74 0
      bazel/check_deps/check_non_test_cc_deps.py
  4. 3 6
      common/BUILD
  5. 1 1
      common/check_test.cpp
  6. 2 2
      common/indirect_value_test.cpp
  7. 66 2
      common/ostream.h
  8. 3 3
      common/string_helpers_test.cpp
  9. 12 6
      compile_flags.txt
  10. 5 0
      executable_semantics/BUILD
  11. 6 5
      executable_semantics/ast/BUILD
  12. 3 2
      executable_semantics/ast/expression_test.cpp
  13. 3 2
      executable_semantics/ast/pattern_test.cpp
  14. 5 3
      executable_semantics/common/BUILD
  15. 1 1
      executable_semantics/common/error_test.cpp
  16. 4 1
      executable_semantics/interpreter/BUILD
  17. 4 1
      executable_semantics/syntax/BUILD
  18. 4 5
      migrate_cpp/cpp_refactoring/BUILD
  19. 3 2
      migrate_cpp/cpp_refactoring/matcher_test_base.h
  20. 2 2
      toolchain/common/BUILD
  21. 1 0
      toolchain/common/yaml_test_helpers.cpp
  22. 4 2
      toolchain/common/yaml_test_helpers.h
  23. 2 4
      toolchain/diagnostics/BUILD
  24. 3 2
      toolchain/diagnostics/diagnostic_emitter_test.cpp
  25. 2 1
      toolchain/diagnostics/mocks.h
  26. 1 3
      toolchain/driver/BUILD
  27. 3 2
      toolchain/driver/driver_test.cpp
  28. 8 12
      toolchain/lexer/BUILD
  29. 4 2
      toolchain/lexer/numeric_literal_test.cpp
  30. 4 2
      toolchain/lexer/string_literal_test.cpp
  31. 3 2
      toolchain/lexer/token_kind_test.cpp
  32. 5 0
      toolchain/lexer/tokenized_buffer.cpp
  33. 5 0
      toolchain/lexer/tokenized_buffer.h
  34. 3 2
      toolchain/lexer/tokenized_buffer_test.cpp
  35. 2 1
      toolchain/lexer/tokenized_buffer_test_helpers.h
  36. 5 9
      toolchain/parser/BUILD
  37. 2 1
      toolchain/parser/parse_node_kind_test.cpp
  38. 2 1
      toolchain/parser/parse_test_helpers.h
  39. 14 0
      toolchain/parser/parse_tree.cpp
  40. 11 0
      toolchain/parser/parse_tree.h
  41. 4 2
      toolchain/parser/parse_tree_test.cpp
  42. 3 2
      toolchain/parser/precedence_test.cpp
  43. 1 3
      toolchain/source/BUILD
  44. 3 2
      toolchain/source/source_buffer_test.cpp

+ 39 - 0
WORKSPACE

@@ -89,6 +89,45 @@ load(
 
 configure_clang_toolchain(name = "bazel_cc_toolchain")
 
+###############################################################################
+# Abseil libraries
+###############################################################################
+
+abseil_version = "4a995b1eaa4a602f0d3a9ff8eac89d4649cd2fe8"
+
+http_archive(
+    name = "com_google_absl",
+    sha256 = "f5021900ff9a6b8f39406d15f460714660ab6b3e727754663d786d75ecad5ee0",
+    strip_prefix = "abseil-cpp-%s" % abseil_version,
+    urls = ["https://github.com/abseil/abseil-cpp/archive/%s.zip" % abseil_version],
+)
+
+###############################################################################
+# GoogleTest libraries
+###############################################################################
+
+googletest_version = "075810f7a20405ea09a93f68847d6e963212fa62"
+
+http_archive(
+    name = "com_google_googletest",
+    sha256 = "19949c33e795197dbb8610672c18bff447dc31faef3257665d69d1bf0884d67b",
+    strip_prefix = "googletest-%s" % googletest_version,
+    urls = ["https://github.com/google/googletest/archive/%s.zip" % googletest_version],
+)
+
+###############################################################################
+# Google Benchmark libraries
+###############################################################################
+
+benchmark_version = "0baacde3618ca617da95375e0af13ce1baadea47"
+
+http_archive(
+    name = "com_github_google_benchmark",
+    sha256 = "19949c33e795197dbb8610672c18bff447dc31faef3257665d69d1bf0884d67b",
+    strip_prefix = "benchmark-%s" % benchmark_version,
+    urls = ["https://github.com/google/benchmark/archive/%s.zip" % benchmark_version],
+)
+
 ###############################################################################
 # LLVM libraries
 ###############################################################################

+ 87 - 0
bazel/check_deps/BUILD

@@ -0,0 +1,87 @@
+# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+# Exceptions. See /LICENSE for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+load("@mypy_integration//:mypy.bzl", "mypy_test")
+
+# This filegroup should contain all the non-test C++ rules in the repository to
+# enable dependency checking. It can be regenerated by running the following
+# query command:
+#
+# ```
+# bazelisk query 'kind("cc.* rule", attr(testonly, 0, //...))'
+# ```
+filegroup(
+    name = "non_test_cc_rules",
+    data = [
+        "//common:check",
+        "//common:indirect_value",
+        "//common:ostream",
+        "//common:string_helpers",
+        "//executable_semantics",
+        "//executable_semantics/ast",
+        "//executable_semantics/ast:class_definition",
+        "//executable_semantics/ast:declaration",
+        "//executable_semantics/ast:expression",
+        "//executable_semantics/ast:library_name",
+        "//executable_semantics/ast:member",
+        "//executable_semantics/ast:paren_contents",
+        "//executable_semantics/ast:pattern",
+        "//executable_semantics/ast:source_location",
+        "//executable_semantics/ast:statement",
+        "//executable_semantics/common:arena",
+        "//executable_semantics/common:error",
+        "//executable_semantics/common:nonnull",
+        "//executable_semantics/interpreter",
+        "//executable_semantics/interpreter:address",
+        "//executable_semantics/interpreter:dictionary",
+        "//executable_semantics/interpreter:exec_program",
+        "//executable_semantics/interpreter:field_path",
+        "//executable_semantics/interpreter:heap",
+        "//executable_semantics/interpreter:stack",
+        "//executable_semantics/interpreter:type_checker",
+        "//executable_semantics/syntax",
+        "//executable_semantics/syntax:bison_wrap",
+        "//migrate_cpp/cpp_refactoring",
+        "//migrate_cpp/cpp_refactoring:fn_inserter",
+        "//migrate_cpp/cpp_refactoring:for_range",
+        "//migrate_cpp/cpp_refactoring:matcher",
+        "//migrate_cpp/cpp_refactoring:var_decl",
+        "//toolchain/diagnostics:diagnostic_emitter",
+        "//toolchain/diagnostics:null_diagnostics",
+        "//toolchain/driver",
+        "//toolchain/driver:carbon",
+        "//toolchain/lexer:character_set",
+        "//toolchain/lexer:numeric_literal",
+        "//toolchain/lexer:string_literal",
+        "//toolchain/lexer:token_kind",
+        "//toolchain/lexer:tokenized_buffer",
+        "//toolchain/parser:parse_node_kind",
+        "//toolchain/parser:parse_tree",
+        "//toolchain/parser:precedence",
+        "//toolchain/source:source_buffer",
+    ],
+)
+
+genquery(
+    name = "non_test_cc_deps.txt",
+    expression = "kind('cc.* rule', deps(//bazel/check_deps:non_test_cc_rules))",
+    opts = [
+        "--notool_deps",
+        "--noimplicit_deps",
+    ],
+    scope = [":non_test_cc_rules"],
+)
+
+py_test(
+    name = "check_non_test_cc_deps",
+    srcs = ["check_non_test_cc_deps.py"],
+    data = [":non_test_cc_deps.txt"],
+    main = "check_non_test_cc_deps.py",
+)
+
+mypy_test(
+    name = "check_non_test_cc_deps_mypy_test",
+    include_imports = True,
+    deps = [":check_non_test_cc_deps"],
+)

+ 74 - 0
bazel/check_deps/check_non_test_cc_deps.py

@@ -0,0 +1,74 @@
+#!/usr/bin/env python3
+
+"""Check that non-test C++ rules only depend on Carbon and LLVM.
+
+Carbon works to ensure its user-visible libraries and binaries only depend on
+their code and LLVM. Among other benefits, this provides a single, simple
+license used for the whole project.
+
+However, we frequently use third-party projects and libraries where useful in
+our test code. Here, we verify that the dependencies of non-test C++ rules only
+include Carbon and LLVM code.
+"""
+
+__copyright__ = """
+Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+Exceptions. See /LICENSE for license information.
+SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+"""
+
+import os
+import sys
+from pathlib import Path
+
+runfiles = Path(os.environ["TEST_SRCDIR"])
+deps_path = (
+    runfiles / "carbon" / "bazel" / "check_deps" / "non_test_cc_deps.txt"
+)
+try:
+    with deps_path.open() as deps_file:
+        deps = deps_file.read().splitlines()
+except FileNotFoundError:
+    sys.exit("ERROR: unable to find deps file: %s" % deps_path)
+
+for dep in deps:
+    print("Checking dependency: " + dep)
+    repo, _, rule = dep.partition("//")
+    if repo == "" and not rule.startswith("third_party"):
+        # Carbon code is always allowed.
+        continue
+    if repo == "@llvm-project":
+        package, _, rule = rule.partition(":")
+
+        # Other packages in the LLVM project shouldn't be accidentally used
+        # in Carbon. We can expand the above list if use cases emerge.
+        if package not in ("llvm", "lld", "clang"):
+            sys.exit(
+                "ERROR: unexpected dependency into the LLVM project: %s" % dep
+            )
+
+        # Check for accidentally using the copy of GoogleTest in LLVM.
+        if rule in ("gmock", "gtest", "gtest_main"):
+            sys.exit(
+                "ERROR: dependency on LLVM's GoogleTest from non-test code: %s"
+                % dep
+            )
+
+        # The rest of LLVM, LLD, and Clang themselves are safe to depend on.
+        continue
+    if repo in ("@llvm_terminfo", "@llvm_zlib"):
+        # These are stubs wrapping system libraries for LLVM. They aren't
+        # distributed and so should be fine.
+        continue
+    if repo in (
+        "@com_google_absl",
+        "@com_google_googletest",
+        "@com_github_google_benchmark",
+    ):
+        # This should never be reached from non-test code, but these targets do
+        # exist. Specially diagnose them to try to provide a more helpful
+        # message.
+        sys.exit("ERROR: dependency only allowed in test code: %s" % dep)
+
+    # Conservatively fail if a dependency isn't explicitly allowed above.
+    sys.exit("ERROR: unknown dependency: %s" % dep)

+ 3 - 6
common/BUILD

@@ -18,8 +18,7 @@ cc_test(
     srcs = ["check_test.cpp"],
     deps = [
         ":check",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
+        "@com_google_googletest//:gtest_main",
     ],
 )
 
@@ -33,8 +32,7 @@ cc_test(
     srcs = ["indirect_value_test.cpp"],
     deps = [
         ":indirect_value",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
+        "@com_google_googletest//:gtest_main",
     ],
 )
 
@@ -61,7 +59,6 @@ cc_test(
     srcs = ["string_helpers_test.cpp"],
     deps = [
         ":string_helpers",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
+        "@com_google_googletest//:gtest_main",
     ],
 )

+ 1 - 1
common/check_test.cpp

@@ -4,7 +4,7 @@
 
 #include "common/check.h"
 
-#include "gtest/gtest.h"
+#include <gtest/gtest.h>
 
 namespace Carbon {
 

+ 2 - 2
common/indirect_value_test.cpp

@@ -4,9 +4,9 @@
 
 #include "common/indirect_value.h"
 
-#include <string>
+#include <gtest/gtest.h>
 
-#include "gtest/gtest.h"
+#include <string>
 
 namespace Carbon {
 namespace {

+ 66 - 2
common/ostream.h

@@ -5,11 +5,14 @@
 #ifndef COMMON_OSTREAM_H_
 #define COMMON_OSTREAM_H_
 
+#include <ostream>
+
+#include "llvm/Support/raw_os_ostream.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace Carbon {
 
-// Support ostream << for types which implement:
+// Support raw_ostream << for types which implement:
 //   void Print(llvm::raw_ostream& out) const;
 template <typename T, typename std::enable_if<std::is_member_function_pointer<
                           decltype(&T::Print)>::value>::type* = nullptr>
@@ -18,7 +21,7 @@ auto operator<<(llvm::raw_ostream& out, const T& obj) -> llvm::raw_ostream& {
   return out;
 }
 
-// Prevents ostream << for pointers to printable types.
+// Prevents raw_ostream << for pointers to printable types.
 template <typename T, typename std::enable_if<std::is_member_function_pointer<
                           decltype(&T::Print)>::value>::type* = nullptr>
 __attribute__((unavailable(
@@ -26,6 +29,67 @@ __attribute__((unavailable(
     "To print as a pointer, cast to void*."))) auto
 operator<<(llvm::raw_ostream& out, const T* /*obj*/) -> llvm::raw_ostream&;
 
+// Support std::ostream << for types which implement:
+//   void Print(llvm::raw_ostream& out) const;
+template <typename T, typename std::enable_if<std::is_member_function_pointer<
+                          decltype(&T::Print)>::value>::type* = nullptr>
+auto operator<<(std::ostream& out, const T& obj) -> std::ostream& {
+  llvm::raw_os_ostream raw_os(out);
+  obj.Print(raw_os);
+  return out;
+}
+
+// Prevents std::ostream << for pointers to printable types.
+template <typename T, typename std::enable_if<std::is_member_function_pointer<
+                          decltype(&T::Print)>::value>::type* = nullptr>
+__attribute__((unavailable(
+    "Received a pointer to a printable type, are you missing a `*`? "
+    "To print as a pointer, cast to void*."))) auto
+operator<<(std::ostream& out, const T* /*obj*/) -> std::ostream&;
+
+// Allow GoogleTest and GoogleMock to print even pointers by dereferencing them.
+// This is important to allow automatic printing of arguments of mocked APIs.
+template <typename T, typename std::enable_if<std::is_member_function_pointer<
+                          decltype(&T::Print)>::value>::type* = nullptr>
+void PrintTo(const T* p, std::ostream* out) {
+  *out << static_cast<const void*>(p);
+
+  // Also print the object if non-null.
+  if (p) {
+    *out << " pointing to " << *p;
+  }
+}
+
 }  // namespace Carbon
 
+namespace llvm {
+
+// Injects an `operator<<` overload into the `llvm` namespace which detects LLVM
+// types with `raw_ostream` overloads and uses that to map to a `std::ostream`
+// overload. This allows LLVM types to be printed to `std::ostream` via their
+// `raw_ostream` operator overloads, which is needed both for logging and
+// testing.
+//
+// To make this overload be unusually low priority, it is designed to take even
+// the `std::ostream` parameter as a template, and SFINAE disable itself unless
+// that template parameter matches `std::ostream`. This ensures that an
+// *explicit* operator will be preferred when provided. Some LLVM types may have
+// this, and so we want to prioritize accordingly.
+//
+// It would be slightly cleaner for LLVM itself to provide this overload in
+// `raw_os_ostream.h` so that we wouldn't need to inject into its namespace, but
+// supporting `std::ostream` isn't a priority for LLVM so we handle it locally
+// instead.
+template <typename S, typename T,
+          typename = std::enable_if_t<std::is_base_of_v<
+              std::ostream, std::remove_reference_t<std::remove_cv_t<S>>>>,
+          typename = std::enable_if_t<!std::is_same_v<
+              std::remove_reference_t<std::remove_cv_t<T>>, raw_ostream>>>
+auto operator<<(S& standard_out, const T& value) -> S& {
+  raw_os_ostream(standard_out) << value;
+  return standard_out;
+}
+
+}  // namespace llvm
+
 #endif  // COMMON_OSTREAM_H_

+ 3 - 3
common/string_helpers_test.cpp

@@ -4,10 +4,10 @@
 
 #include "common/string_helpers.h"
 
-#include <string>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
 
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
+#include <string>
 
 using ::testing::Eq;
 using ::testing::Optional;

+ 12 - 6
compile_flags.txt

@@ -37,7 +37,6 @@
 -DGTEST_HAS_RTTI=0
 -D__STDC_LIMIT_MACROS
 -D__STDC_CONSTANT_MACROS
--DGTEST_USE_OWN_TR1_TUPLE=1
 -iquote
 .
 -iquote
@@ -62,19 +61,26 @@ bazel-bin/external/llvm_zlib
 bazel-execroot/external/bazel_tools
 -iquote
 bazel-bin/external/bazel_tools
--Ibazel-execroot/external/llvm-project/llvm/utils/unittest/googletest/src
 -isystem
 bazel-execroot/external/llvm-project/llvm/include
 -isystem
 bazel-bin/external/llvm-project/llvm/include
 -isystem
-bazel-execroot/external/llvm-project/llvm/utils/unittest/googlemock/include
+bazel-execroot/external/com_google_googletest/googlemock
 -isystem
-bazel-bin/external/llvm-project/llvm/utils/unittest/googlemock/include
+bazel-bin/external/com_google_googletest/googlemock
 -isystem
-bazel-execroot/external/llvm-project/llvm/utils/unittest/googletest/include
+bazel-execroot/external/com_google_googletest/googlemock/include
 -isystem
-bazel-bin/external/llvm-project/llvm/utils/unittest/googletest/include
+bazel-bin/external/com_google_googletest/googlemock/include
+-isystem
+bazel-execroot/external/com_google_googletest/googletest
+-isystem
+bazel-bin/external/com_google_googletest/googletest
+-isystem
+bazel-execroot/external/com_google_googletest/googletest/include
+-isystem
+bazel-bin/external/com_google_googletest/googletest/include
 -std=c++17
 -stdlib=libc++
 -no-canonical-prefixes

+ 5 - 0
executable_semantics/BUILD

@@ -4,6 +4,11 @@
 
 load("//bazel/testing:lit_test.bzl", "lit_test")
 
+package(default_visibility = [
+    "//bazel/check_deps:__pkg__",
+    "//executable_semantics:__subpackages__",
+])
+
 cc_binary(
     name = "executable_semantics",
     srcs = ["main.cpp"],

+ 6 - 5
executable_semantics/ast/BUILD

@@ -2,7 +2,10 @@
 # Exceptions. See /LICENSE for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-package(default_visibility = ["//executable_semantics:__subpackages__"])
+package(default_visibility = [
+    "//bazel/check_deps:__pkg__",
+    "//executable_semantics:__subpackages__",
+])
 
 cc_library(
     name = "ast",
@@ -62,8 +65,7 @@ cc_test(
     deps = [
         ":expression",
         ":paren_contents",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
+        "@com_google_googletest//:gtest_main",
     ],
 )
 
@@ -112,9 +114,8 @@ cc_test(
     deps = [
         ":paren_contents",
         ":pattern",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
     ],
 )
 

+ 3 - 2
executable_semantics/ast/expression_test.cpp

@@ -4,12 +4,13 @@
 
 #include "executable_semantics/ast/expression.h"
 
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include <string>
 
 #include "executable_semantics/ast/paren_contents.h"
 #include "executable_semantics/common/arena.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
 #include "llvm/Support/Casting.h"
 
 namespace Carbon {

+ 3 - 2
executable_semantics/ast/pattern_test.cpp

@@ -4,11 +4,12 @@
 
 #include "executable_semantics/ast/pattern.h"
 
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include "executable_semantics/ast/expression.h"
 #include "executable_semantics/ast/paren_contents.h"
 #include "executable_semantics/common/arena.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
 #include "llvm/Support/Casting.h"
 
 namespace Carbon {

+ 5 - 3
executable_semantics/common/BUILD

@@ -2,7 +2,10 @@
 # Exceptions. See /LICENSE for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-package(default_visibility = ["//executable_semantics:__subpackages__"])
+package(default_visibility = [
+    "//bazel/check_deps:__pkg__",
+    "//executable_semantics:__subpackages__",
+])
 
 cc_library(
     name = "arena",
@@ -25,8 +28,7 @@ cc_test(
     srcs = ["error_test.cpp"],
     deps = [
         ":error",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
+        "@com_google_googletest//:gtest_main",
     ],
 )
 

+ 1 - 1
executable_semantics/common/error_test.cpp

@@ -4,7 +4,7 @@
 
 #include "executable_semantics/common/error.h"
 
-#include "gtest/gtest.h"
+#include <gtest/gtest.h>
 
 namespace Carbon {
 namespace {

+ 4 - 1
executable_semantics/interpreter/BUILD

@@ -2,7 +2,10 @@
 # Exceptions. See /LICENSE for license information.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
-package(default_visibility = ["//executable_semantics:__pkg__"])
+package(default_visibility = [
+    "//bazel/check_deps:__pkg__",
+    "//executable_semantics:__pkg__",
+])
 
 # These currently have to be a single build rule because of a dependency cycle
 # in printing.

+ 4 - 1
executable_semantics/syntax/BUILD

@@ -4,7 +4,10 @@
 
 load("@mypy_integration//:mypy.bzl", "mypy_test")
 
-package(default_visibility = ["//executable_semantics:__pkg__"])
+package(default_visibility = [
+    "//bazel/check_deps:__pkg__",
+    "//executable_semantics:__pkg__",
+])
 
 cc_library(
     name = "bison_wrap",

+ 4 - 5
migrate_cpp/cpp_refactoring/BUILD

@@ -34,10 +34,9 @@ cc_library(
     hdrs = ["matcher_test_base.h"],
     deps = [
         ":matcher",
+        "@com_google_googletest//:gtest",
         "@llvm-project//clang:ast_matchers",
         "@llvm-project//clang:tooling",
-        "@llvm-project//llvm:gmock",
-        "@llvm-project//llvm:gtest",
     ],
 )
 
@@ -56,8 +55,8 @@ cc_test(
     deps = [
         ":fn_inserter",
         ":matcher_test_base",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//clang:tooling",
-        "@llvm-project//llvm:gtest_main",
     ],
 )
 
@@ -74,8 +73,8 @@ cc_test(
     deps = [
         ":for_range",
         ":matcher_test_base",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//clang:tooling",
-        "@llvm-project//llvm:gtest_main",
     ],
 )
 
@@ -92,7 +91,7 @@ cc_test(
     deps = [
         ":matcher_test_base",
         ":var_decl",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//clang:tooling",
-        "@llvm-project//llvm:gtest_main",
     ],
 )

+ 3 - 2
migrate_cpp/cpp_refactoring/matcher_test_base.h

@@ -5,11 +5,12 @@
 #ifndef MIGRATE_CPP_CPP_REFACTORING_MATCHER_TEST_BASE_H_
 #define MIGRATE_CPP_CPP_REFACTORING_MATCHER_TEST_BASE_H_
 
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Tooling/Core/Replacement.h"
 #include "clang/Tooling/Tooling.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
 #include "migrate_cpp/cpp_refactoring/matcher_manager.h"
 
 namespace Carbon {

+ 2 - 2
toolchain/common/BUILD

@@ -10,7 +10,7 @@ cc_library(
     srcs = ["yaml_test_helpers.cpp"],
     hdrs = ["yaml_test_helpers.h"],
     deps = [
-        "@llvm-project//llvm:gmock",
-        "@llvm-project//llvm:gtest",
+        "//common:ostream",
+        "@com_google_googletest//:gtest",
     ],
 )

+ 1 - 0
toolchain/common/yaml_test_helpers.cpp

@@ -4,6 +4,7 @@
 
 #include "toolchain/common/yaml_test_helpers.h"
 
+#include "llvm/ADT/SmallString.h"
 #include "llvm/Support/YAMLParser.h"
 
 namespace Carbon::Testing::Yaml {

+ 4 - 2
toolchain/common/yaml_test_helpers.h

@@ -47,13 +47,15 @@
 #ifndef TOOLCHAIN_COMMON_YAML_TEST_HELPERS_H_
 #define TOOLCHAIN_COMMON_YAML_TEST_HELPERS_H_
 
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include <iomanip>
 #include <iostream>
 #include <sstream>
 #include <variant>
 
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
+#include "common/ostream.h"
 
 namespace Carbon {
 namespace Testing {

+ 2 - 4
toolchain/diagnostics/BUILD

@@ -26,8 +26,8 @@ cc_library(
     hdrs = ["mocks.h"],
     deps = [
         ":diagnostic_emitter",
+        "@com_google_googletest//:gtest",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gmock",
     ],
 )
 
@@ -37,9 +37,7 @@ cc_test(
     deps = [
         ":diagnostic_emitter",
         ":mocks",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gmock",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
     ],
 )

+ 3 - 2
toolchain/diagnostics/diagnostic_emitter_test.cpp

@@ -4,8 +4,9 @@
 
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "toolchain/diagnostics/mocks.h"

+ 2 - 1
toolchain/diagnostics/mocks.h

@@ -5,7 +5,8 @@
 #ifndef TOOLCHAIN_DIAGNOSTICS_MOCKS_H_
 #define TOOLCHAIN_DIAGNOSTICS_MOCKS_H_
 
-#include "gmock/gmock.h"
+#include <gmock/gmock.h>
+
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 
 namespace Carbon {

+ 1 - 3
toolchain/driver/BUILD

@@ -27,10 +27,8 @@ cc_test(
         ":driver",
         "//toolchain/common:yaml_test_helpers",
         "//toolchain/lexer:tokenized_buffer_test_helpers",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gmock",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
     ],
 )
 

+ 3 - 2
toolchain/driver/driver_test.cpp

@@ -4,8 +4,9 @@
 
 #include "toolchain/driver/driver.h"
 
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/SourceMgr.h"

+ 8 - 12
toolchain/lexer/BUILD

@@ -19,9 +19,8 @@ cc_test(
     srcs = ["token_kind_test.cpp"],
     deps = [
         ":token_kind",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
     ],
 )
 
@@ -58,11 +57,10 @@ cc_test(
     deps = [
         ":numeric_literal",
         ":test_helpers",
+        "//common:ostream",
         "//toolchain/diagnostics:diagnostic_emitter",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gmock",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
     ],
 )
 
@@ -95,11 +93,10 @@ cc_test(
     deps = [
         ":string_literal",
         ":test_helpers",
+        "//common:ostream",
         "//toolchain/diagnostics:diagnostic_emitter",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gmock",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
     ],
 )
 
@@ -124,6 +121,7 @@ cc_library(
         ":numeric_literal",
         ":string_literal",
         ":token_kind",
+        "//common:ostream",
         "//toolchain/diagnostics:diagnostic_emitter",
         "//toolchain/source:source_buffer",
         "@llvm-project//llvm:Support",
@@ -136,8 +134,8 @@ cc_library(
     hdrs = ["tokenized_buffer_test_helpers.h"],
     deps = [
         ":tokenized_buffer",
+        "@com_google_googletest//:gtest",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gmock",
     ],
 )
 
@@ -150,10 +148,8 @@ cc_test(
         "//toolchain/common:yaml_test_helpers",
         "//toolchain/diagnostics:diagnostic_emitter",
         "//toolchain/diagnostics:mocks",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gmock",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
     ],
 )
 

+ 4 - 2
toolchain/lexer/numeric_literal_test.cpp

@@ -4,12 +4,14 @@
 
 #include "toolchain/lexer/numeric_literal.h"
 
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include <iterator>
 #include <memory>
 #include <vector>
 
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
+#include "common/ostream.h"
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 #include "toolchain/lexer/test_helpers.h"
 

+ 4 - 2
toolchain/lexer/string_literal_test.cpp

@@ -4,8 +4,10 @@
 
 #include "toolchain/lexer/string_literal.h"
 
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "common/ostream.h"
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 #include "toolchain/lexer/test_helpers.h"
 

+ 3 - 2
toolchain/lexer/token_kind_test.cpp

@@ -4,10 +4,11 @@
 
 #include "toolchain/lexer/token_kind.h"
 
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include <cstring>
 
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
 #include "llvm/ADT/StringRef.h"
 
 namespace Carbon {

+ 5 - 0
toolchain/lexer/tokenized_buffer.cpp

@@ -863,6 +863,11 @@ auto TokenizedBuffer::AddToken(TokenInfo info) -> Token {
   return Token(static_cast<int>(token_infos.size()) - 1);
 }
 
+auto TokenizedBuffer::TokenIterator::Print(llvm::raw_ostream& output) const
+    -> void {
+  output << token.index;
+}
+
 auto TokenizedBuffer::SourceBufferLocationTranslator::GetLocation(
     const char* loc) -> Diagnostic::Location {
   assert(llvm::is_sorted(std::array{buffer_->source->Text().begin(), loc,

+ 5 - 0
toolchain/lexer/tokenized_buffer.h

@@ -8,6 +8,7 @@
 #include <cstdint>
 #include <iterator>
 
+#include "common/ostream.h"
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Optional.h"
@@ -15,6 +16,7 @@
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/iterator.h"
 #include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/raw_ostream.h"
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 #include "toolchain/lexer/token_kind.h"
 #include "toolchain/source/source_buffer.h"
@@ -195,6 +197,9 @@ class TokenizedBuffer {
       return *this;
     }
 
+    // Prints the raw token index.
+    auto Print(llvm::raw_ostream& output) const -> void;
+
    private:
     friend class TokenizedBuffer;
 

+ 3 - 2
toolchain/lexer/tokenized_buffer_test.cpp

@@ -4,10 +4,11 @@
 
 #include "toolchain/lexer/tokenized_buffer.h"
 
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include <iterator>
 
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Sequence.h"

+ 2 - 1
toolchain/lexer/tokenized_buffer_test_helpers.h

@@ -5,7 +5,8 @@
 #ifndef TOOLCHAIN_LEXER_TOKENIZED_BUFFER_TEST_HELPERS_H_
 #define TOOLCHAIN_LEXER_TOKENIZED_BUFFER_TEST_HELPERS_H_
 
-#include "gmock/gmock.h"
+#include <gmock/gmock.h>
+
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/YAMLParser.h"

+ 5 - 9
toolchain/parser/BUILD

@@ -19,9 +19,8 @@ cc_test(
     srcs = ["parse_node_kind_test.cpp"],
     deps = [
         ":parse_node_kind",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
     ],
 )
 
@@ -51,8 +50,8 @@ cc_library(
         ":parse_node_kind",
         ":parse_tree",
         "//toolchain/lexer:tokenized_buffer",
+        "@com_google_googletest//:gtest",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gmock",
     ],
 )
 
@@ -63,14 +62,13 @@ cc_test(
         ":parse_node_kind",
         ":parse_test_helpers",
         ":parse_tree",
+        "//common:ostream",
         "//toolchain/common:yaml_test_helpers",
         "//toolchain/diagnostics:diagnostic_emitter",
         "//toolchain/diagnostics:mocks",
         "//toolchain/lexer:tokenized_buffer",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gmock",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
     ],
 )
 
@@ -103,8 +101,6 @@ cc_test(
     deps = [
         ":precedence",
         "//toolchain/lexer:token_kind",
-        "@llvm-project//llvm:gmock",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
+        "@com_google_googletest//:gtest_main",
     ],
 )

+ 2 - 1
toolchain/parser/parse_node_kind_test.cpp

@@ -4,9 +4,10 @@
 
 #include "toolchain/parser/parse_node_kind.h"
 
+#include <gtest/gtest.h>
+
 #include <cstring>
 
-#include "gtest/gtest.h"
 #include "llvm/ADT/StringRef.h"
 
 namespace Carbon {

+ 2 - 1
toolchain/parser/parse_test_helpers.h

@@ -5,12 +5,13 @@
 #ifndef TOOLCHAIN_PARSER_PARSE_TEST_HELPERS_H_
 #define TOOLCHAIN_PARSER_PARSE_TEST_HELPERS_H_
 
+#include <gmock/gmock.h>
+
 #include <ostream>
 #include <string>
 #include <utility>
 #include <vector>
 
-#include "gmock/gmock.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"

+ 14 - 0
toolchain/parser/parse_tree.cpp

@@ -199,4 +199,18 @@ auto ParseTree::Verify() const -> bool {
   return true;
 }
 
+auto ParseTree::Node::Print(llvm::raw_ostream& output) const -> void {
+  output << GetIndex();
+}
+
+auto ParseTree::PostorderIterator::Print(llvm::raw_ostream& output) const
+    -> void {
+  output << node.GetIndex();
+}
+
+auto ParseTree::SiblingIterator::Print(llvm::raw_ostream& output) const
+    -> void {
+  output << node.GetIndex();
+}
+
 }  // namespace Carbon

+ 11 - 0
toolchain/parser/parse_tree.h

@@ -7,10 +7,12 @@
 
 #include <iterator>
 
+#include "common/ostream.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/iterator.h"
 #include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/raw_ostream.h"
 #include "toolchain/diagnostics/diagnostic_emitter.h"
 #include "toolchain/lexer/tokenized_buffer.h"
 #include "toolchain/parser/parse_node_kind.h"
@@ -249,6 +251,9 @@ class ParseTree::Node {
   // FIXME: Maybe we can switch to stream operator overloads?
   [[nodiscard]] auto GetIndex() const -> int { return index; }
 
+  // Prints the node index.
+  auto Print(llvm::raw_ostream& output) const -> void;
+
  private:
   friend ParseTree;
   friend Parser;
@@ -298,6 +303,9 @@ class ParseTree::PostorderIterator
     return *this;
   }
 
+  // Prints the underlying node index.
+  auto Print(llvm::raw_ostream& output) const -> void;
+
  private:
   friend class ParseTree;
 
@@ -340,6 +348,9 @@ class ParseTree::SiblingIterator
     return *this;
   }
 
+  // Prints the underlying node index.
+  auto Print(llvm::raw_ostream& output) const -> void;
+
  private:
   friend class ParseTree;
 

+ 4 - 2
toolchain/parser/parse_tree_test.cpp

@@ -4,10 +4,12 @@
 
 #include "toolchain/parser/parse_tree.h"
 
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include <forward_list>
 
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
+#include "common/ostream.h"
 #include "llvm/ADT/Sequence.h"
 #include "llvm/Support/SourceMgr.h"
 #include "toolchain/common/yaml_test_helpers.h"

+ 3 - 2
toolchain/parser/precedence_test.cpp

@@ -4,8 +4,9 @@
 
 #include "toolchain/parser/precedence.h"
 
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
 #include "toolchain/lexer/token_kind.h"
 
 namespace Carbon {

+ 1 - 3
toolchain/source/BUILD

@@ -16,9 +16,7 @@ cc_test(
     srcs = ["source_buffer_test.cpp"],
     deps = [
         ":source_buffer",
+        "@com_google_googletest//:gtest_main",
         "@llvm-project//llvm:Support",
-        "@llvm-project//llvm:gmock",
-        "@llvm-project//llvm:gtest",
-        "@llvm-project//llvm:gtest_main",
     ],
 )

+ 3 - 2
toolchain/source/source_buffer_test.cpp

@@ -4,7 +4,8 @@
 
 #include "toolchain/source/source_buffer.h"
 
-#include "gtest/gtest.h"
+#include <gtest/gtest.h>
+
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/Support/FileSystem.h"
@@ -49,7 +50,7 @@ TEST(SourceBufferTest, FileRep) {
 
   auto expected_buffer = SourceBuffer::CreateFromFile(test_file_path);
   ASSERT_TRUE(static_cast<bool>(expected_buffer))
-      << "Error message: " << expected_buffer.takeError();
+      << "Error message: " << toString(expected_buffer.takeError());
 
   SourceBuffer& buffer = *expected_buffer;